Blankman
Blankman

Reputation: 267140

Normalizing my JSON response using normalizr with redux

I'm trying to reshape my Redux store so I can query by and filter my data easily.

I have an API endpoint that returns back an order. The order looks like this at a high level:

Order
 + references
    + item_details
       - category_id
       - product_id
       - product

So an order has many references, and the references have many item_details. The item details has a category and product.

  const data = {
    id: 3939393,
    discount: 0,

    references: [
    {
      id: 123,
      order_id: 3939393,
      name: "order 1",
      item_details: [
        {
          id: 100,
          order_id: 3939393,
          product_id: 443,
          sort_order: 1,
          category_id: 400,
          product: {
            id: 443,
            name: "hello world",
            price: 199
          }
        },
        {
          id: 200,
          order_id: 3939393,
          product_id: 8080,
          sort_order: 2,
          category_id: 500,
          product: {
            id: 8080,
            name: "hello json",
            price: 299
          }
        }
      ]
    }
  ]
};

export default data;

So far my schema definitions look like this:

export const productSchema = new schema.Entity("products");
export const itemDetailSchema = new schema.Entity("itemDetails", {
  product: productSchema
});
export const references = new schema.Entity("references", {
  item_details: new schema.Array(itemDetailSchema)
});
export const orderSchema = new schema.Entity("orders");

const result = normalize(data, orderSchema);

console.log("result is: " + JSON.stringify(result));
  1. How can I get the products in its own section in the normalized JSON? Currently the products are still embedded inside the JSON.

Would I use normalizr to create state "index" type looks like this:

productsInReferences: {
  123: [400, 8080]
}

If not, how exactly to I generate these types of JSON lookups?

I created a codesandbox with my code so far. https://codesandbox.io/s/xpl4n9w31q

Upvotes: 0

Views: 1014

Answers (1)

garyvh2
garyvh2

Reputation: 11

I usually think Normalization schemes from the deepest nested structure all the way to the one containing the data for those cases. Remember that you can do explicit array definition through [someSchema], also every level should be contained on a nested schema, in this case you forgot the references: [referenceSchema] on the orderSchema.

The correct normalization would be:

// Product Schema
const productSchema = new schema.Entity("products");
// Item detail schema containing a product schema OBJECT within the property product
const itemDetailSchema = new schema.Entity("itemDetails", {
    product: productSchema
});
// Reference schema containing an ARRAY of itemDetailSchemes within the property item_details
const referenceSchema = new schema.Entity("references", {
    item_details: [itemDetailSchema]
});
// Order schema containing an ARRAY of reference schemes within the property references
const orderSchema = new schema.Entity("orders", {
    references: [referenceSchema]
});


const result = normalize(data, orderSchema);
console.dir(result);

This would be the result after normalizing.

Object
    entities:
        itemDetails: {100: {…}, 200: {…}}
        orders: {3939393: {…}}
        products: {443: {…}, 8080: {…}}
        references: {123: {…}}
    result: 3939393

Upvotes: 0

Related Questions