Search code examples
ecmascript-6reduxnormalizr

how to specify normalizr schema for nested object


Input:

provider: {
                id: 1,
                name: 'abc',
                npi: 1234,
                credentials: [{
                      id: 1,
                      description: 'abc'
                 }],
                specialties: [{
                      id: 1,
                      description: 'abc'
                 }],
                 supervisingPhysician: { 
                          id: 2,
                          name: 'xyz',
                          npi: 56789,
                          credentials: [{
                                id: 1,
                                description: 'abc'
                           }],
                        }
           }

Schema

import { schema } from 'normalizr';
import _ from 'lodash';

let specialtySchema = new schema.Entity('specialties');

export const providerSchema = new schema.Entity('provider', {
    specialties: [specialtySchema], primarySpecialty: specialtySchema
});

expected Output: (something like)

entities: { providers: { "1" : {..., supervisingPhysician: 2, specialties: 1},
                         "2" : {..., specialties: 1}
                       }, 
            specialties: {"1" : {...specialty object}
          }

in my example both my root provider object and nested supervisingPhysician object are same type (a provider) of object.

How can I define the schema such that I can normalize both root and supervisingPhysician together.

Thanks for looking at this.


Solution

  • This can be achieved pretty easily by naming the entity key of the supervisingPhysician-entity 'providers'.

    // define normal schema credentials and specialties
    const credentialSchema = new schema.Entity('credentials');
    const specialtySchema = new schema.Entity('specialties');
    
    // define the supervisingPhysician schema with 'providers' as key
    // normalizr will now put all supervisingPhysicians directly into the providers object
    const supervisingPhysicianSchema = new schema.Entity('providers', {
      credentials: [credentialSchema]
    });
    
    // define 'root'-provider schema
    const providerSchema = new schema.Entity('providers', {
      credentials: [credentialSchema],
      specialties: [specialtySchema],
      supervisingPhysician: supervisingPhysicianSchema
    });
    
    // the whole data schema
    const dataSchema = { provider: providerSchema };
    
    // ready to normalize
    normalize(input, dataSchema);
    

    This will give you the following result:

    {
        entities: {
            credentials: {
                1: {
                    id: 1,
                    description: "abc"
                }
            },
            specialties: {
                1: {
                    id: 1,
                    description: "abc"
                }
            },
            providers: {
                1: {
                    id: 1,
                    name: "abc",
                    npi: 1234,
                    credentials: [ 1 ],
                    specialties: [ 1 ],
                    supervisingPhysician: 2
                },
                2: {
                    id: 2,
                    name: "xyz",
                    npi: 56789,
                    credentials: [ 1 ]
                }
            }
        },
        result: {
            provider: 1
        }
    }
    

    For clarification and reference, this is how I declared input:

    const input = {
      provider: {
        id: 1,
        name: "abc",
        npi: 1234,
        credentials: [{ id: 1, description: "abc" }],
        specialties: [{ id: 1, description: "abc" }],
        supervisingPhysician: {
          id: 2,
          name: "xyz",
          npi: 56789,
          credentials: [{ id: 1, description: "abc" }]
        }
      }
    };