Lars
Lars

Reputation: 574

What's the best way to replace generated ID with server ID in Redux Application?

I'm playing around with React and Redux and trying to build a simple sample application. I wanna create entities and send the created entities, to the server, then, grab the server response and set correct id from the server in the created entity.

Currently, I generate a fakeId while waiting for the definitive Id, and when the server responds, replace the fakeId with the correct id.

This is a running example, whith the most relevant lines marked:

http://jsbin.com/duyovo/edit?js,console,output#J:L91-101

Is this the correct way of doing this? or is there another way? I'm building this app to learn React and Redux, and I want to learn it the correct way.

Upvotes: 2

Views: 1240

Answers (1)

Ashley Coolman
Ashley Coolman

Reputation: 11585

The jsbin has an error, and without a working example I'm having trouble parsing this (you may wanna fix that). But yeah, if the server is generating the id it seems like an ok strategy.

I don't like how you reuse case ADD_GROUP based on the "shape" of the response.

Perhaps to neaten things you might split the action into a synchronous and asynchronous sibling using redux-thunk.

WARNING:

This is just pseudocode to give you an idea of what the end product would look like if you used Redux-thunk. It may not be a drastically different strategy, but it might be considered a neater way of doing it.

So you could have an initial action to render a loading item:

var addGroup = (name, fakeId) => ({
    type: ADD_GROUP,
    name,
    fakeId
})

And then twin actions (one sync, the other async) to update from the server.

First the synchronous one, that will (finally) be called once the response is back:

var updateGroupFromServer = (id, name, fakeId) => ({
    type: UPDATE_GROUP_FROM_SERVER,
    name,
    id,
    fakeId
})

Second, the ayschronous one, which you attach to your button:

export const updateGroupFromServerAsync = (name, fakeId) => {

    // Update state with something temp
    store.dispatch(addGroupLoading(name, fakeId));

    // Go get the id from server
    return dispatch => {
      return new Promise(
        (done, fail) => {
          action
            .request
            .json()
            .then(json => {
              mockServer.addGroup(json.name)).then( res => {
                dispatch(
                  /* Now its ready, it calls your async action*/
                  updateGroupFromServer({ id: res.id, name, fakeId}) 
                );
                done();
              }
            )
            }
        )
    };
};

And then you change your action dispatch to:

      <button onClick={() => {
          updateGroupFromServerAsync(
              this.inputGroup.value,
              Date.now()
          )}>
         Add group
      </button>

And then you would need to add reducers to handle them accordingly. Edit: Added a better solution

Upvotes: 1

Related Questions