Andrew Losseff
Andrew Losseff

Reputation: 373

Normalizr with Redux with nested array of objects

I'm just getting started with using normalizr with Redux, and I can't make it work. Even though I can do it with plain JavaScript.

I have an array of objects

const data = [
  {
    data_detail: [
      {
        category: 'newCategory',
        _id: '123',
      },
    ],
    _id: 'abc_id',
    customer: {
      _id: '456',
      email: '[email protected]',
      name: 'Bob',
    },
    date: '2021-01-10T01:51:24.387Z',
  },
];

And I need to transform it to

const normalizedResponse = {
  customers: {
    '456': {
      _id: '456',
      email: '[email protected]',
      name: 'Bob',
    },
  },
  details: {
    '123': {
      category: 'newCategory',
      _id: '123',
    },
  },
  orders: {
   'abc_id: {
      order_detail: [123],
      _id: 'abc_id',
      customer: '456',
      date: '2021-01-10T01:51:24.387Z',
    },
  },
};

Step 1: Display just orders

What I do:

const userSchema = new schema.Entity(
  'orders',
  );

const userListSchema = new schema.Array(userSchema);


const normalizedData = normalize(data, userListSchema);

What I get

{
  "entities": {
    "orders": {
      "abc_id": {
        "data_detail": [
          {
            "category": "newCategory",
            "id": "123"
          }
        ],
        "id": "abc_id",
        "customer": {
          "id": "456",
          "email": "[email protected]",
          "name": "Bob"
        },
        "date": "2021-01-10T01:51:24.387Z"
      },
      "abc_id-02": {
        "data_detail": [
          {
            "category": "newCategory1",
            "id": "123-02"
          }
        ],
        "id": "abc_id-02",
        "customer": {
          "id": "456-02",
          "email": "[email protected]",
          "name": "Bob"
        },
        "date": "2001-01-10T01:51:24.387Z"
      }
    }
  },
  "result": [
    "abc_id",
    "abc_id-02"
  ]
}

What I'm trying to get:

 orders: {
   'abc_id: {
      order_detail: [123],
      _id: 'abc_id',
      customer: '456',
      date: '2021-01-10T01:51:24.387Z',
    },
  },

The question: How to remove some fields from orders and add new ones?

Upvotes: 0

Views: 467

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42188

You have 3 different entity types in your data object. First draft out a schema for each of them:

const detail = new schema.Entity('details');

const customer = new schema.Entity('customers');

const order = new schema.Entity('orders');

Then go back and fill in the relationships. It looks like order is the outermost entity. An order contains an array of details/categories and a single customer.

const order = new schema.Entity('orders', {
  data_detail: [detail],
  customer,
});

All of your entities use _id instead of id, so you need to set the idAttribute.

Your data is an array of order. You can use new schema.Array(order) but you can also just use [order].

Here's your final code:

const customer = new schema.Entity("customers", {}, { idAttribute: "_id" });

const detail = new schema.Entity("details", {}, { idAttribute: "_id" });

const order = new schema.Entity(
  "orders",
  {
    data_detail: [detail],
    customer
  },
  { idAttribute: "_id" }
);

const normalizedData = normalize(data, [order]);

That gives you:

{
  "entities": {
    "details": { 
      "123": { 
        "category": "newCategory", 
        "_id": "123" 
        } 
      },
    "customers": {
      "456": { 
        "_id": "456", 
        "email": "[email protected]", 
        "name": "Bob"
      }
    },
    "orders": {
      "abc_id": {
        "data_detail": ["123"],
        "_id": "abc_id",
        "customer": "456",
        "date": "2021-01-10T01:51:24.387Z"
      }
    }
  },
  "result": ["abc_id"]
}

Upvotes: 1

Related Questions