1

How can I handle relationships using Flux?

Lets say I have a Employee

{
    id: 1
    name: "Employee",
    position: "Manager"
}

I have some log entries retrieved from the server api, that have a reference to employees

[
    {
        id: 1,
        subject: "Subject",
        employee: {
            id: 1
            name: "Employee",
            position: "Manager"
        }
    },

    {
        id: 2,
        subject: "Subject",
        employee: {
            id: 1
            name: "Employee",
            position: "Manager"
        }
    }   
]

Currently I have 2 stores EmployeeStore and LogEntryStore.

The problem: If a employee changes his name a EMPLOYEE_UPDATED event would be triggered and the EmployeeStore will change the employee, but the LogEntryStore will still have the "outdated" employee.

Should every store that have a relationship also listen to EMPLOYEE_UPDATED? This seems inefficient to me.

How should I handle this?

TryingToImprove
  • 7,047
  • 4
  • 30
  • 39

1 Answers1

0

This is a difficult question to answer because the solution depends on what is best for your application and how your data is structured. The best approach i've found is to think about in a similar way that you would structuring a database, e.g. structuring your stores around what your most common updates/queries.

In your case, it seems more likely that logs are going to be updated than employees are going to change. I'd simply listen to both events in your employee and logs stores, have the logStore update all relevant logs when an employee changes. So yes, every store with a dependency on the employeeStore would listen to employee related updates. Frameworks like fluxxor solve this by allowing stores to listen to other stores. An example of a dispatch handler in the logStore

handleChange: function (type, payload) {
    switch (type) {
      case 'EMPLOYEE_UPDATED':
        dispatcher.waitFor([employeeStore.dispatchToken]);
        Object.keys(this._items).forEach(function (key) {
          var log = this._items[key];
          log.employee = employeeStore.get(log.employee.id);
        }.bind(this));
        this.emitChange();
      break

      case 'LOG_UPDATE':
        dispatcher.waitFor([employeeStore.dispatchToken]);
        payload.data.forEach(this.getEmployeesForLog.bind(this));
        this.emitChange();
      break;
    }
  }

Here's a working example using your dataset: jsbin

Another approach would be to have whatever controller/view that is concerned with your store listen to relevant stores and build the data for itself or its child views, but it seems best to have the responsibility lie in the stores themselves.

For reference, the following questions may be helpful.

Community
  • 1
  • 1
Nick Tomlin
  • 28,402
  • 11
  • 61
  • 90