Normalizr - is it a way to generate IDs for non-id

2019-08-19 12:44发布

I'm using normalizr util to process API response based on non-ids model. As I know, typically normalizr works with ids model, but maybe there is a some way to generate ids "on the go"?

My API response example:

```

// input data:
const inputData = {
  doctors: [
   {
    name: Jon,
    post: chief
   },
   {
    name: Marta,
    post: nurse
   },
   //....
}

// expected output data:
const outputData = {
  entities: {
   nameCards : {
    uniqueID_0: { id: uniqueID_0, name: Jon, post: uniqueID_3 },
    uniqueID_1: { id: uniqueID_1, name: Marta, post: uniqueID_4 }
   },
   positions: {
    uniqueID_3: { id: uniqueID_3, post: chief },
    uniqueID_4: { id: uniqueID_4, post: nurse }
   }
  },
  result: uniqueID_0
}

```

P.S. I heard from someone about generating IDs "by the hood" in normalizr for such cases as my, but I did found such solution.

2条回答
三岁会撩人
2楼-- · 2019-08-19 13:31

As mentioned in this issue:

Normalizr is never going to be able to generate unique IDs for you. We don't do any memoization or anything internally, as that would be unnecessary for most people.

Your working solution is okay, but will fail if you receive one of these entities again later from another API endpoint.

My recommendation would be to find something that's constant and unique on your entities and use that as something to generate unique IDs from.

And then, as mentioned in the docs, you need to set idAttribute to replace 'id' with another key:

const data = { id_str: '123', url: 'https://twitter.com', user: { id_str: '456', name: 'Jimmy' } };

const user = new schema.Entity('users', {}, { idAttribute: 'id_str' });
const tweet = new schema.Entity('tweets', { user: user }, { 
    idAttribute: 'id_str',
    // Apply everything from entityB over entityA, except for "favorites"
    mergeStrategy: (entityA, entityB) => ({
      ...entityA,
      ...entityB,
      favorites: entityA.favorites
    }),
    // Remove the URL field from the entity
    processStrategy: (entity) => omit(entity, 'url')
});

const normalizedData = normalize(data, tweet);

EDIT

You can always provide unique id's using external lib or by hand:

inputData.doctors = inputData.doctors.map((doc, idx) => ({ 
  ...doc, 
  id: `doctor_${idx}`
}))
查看更多
做个烂人
3楼-- · 2019-08-19 13:43

Have a processStrategy which is basically a function and in that function assign your id's there, ie. value.id = uuid(). Visit the link below to see an example https://github.com/paularmstrong/normalizr/issues/256

查看更多
登录 后发表回答