Iterating through an object leaves undefined

Viewed 62

I have an object rawUser in rawUser I have two arrays insertConfigurations & packagingInstructions

I'm currently mapping through these two arrays.

This is working as expected. Here is my code snippet:

const rawUser = {
  id: 1,
  name: "Barnes",
  config: {
    insertConfigurations: [{
        id: "B22",
        type: "Insert",
        title: "Barnes",
        subtitle: "Welcome Book",
        dropInConditional: "FIRST"
    }],
    packagingInstructions: [{
      id: "B22",
      type: "sticker",
      title: "Barnes",
      packagingType: "STICKER"
    }]
  }
};

console.log(dataReturn());

function dataReturn() {
  return {
    id: rawUser.id,
    name: rawUser.name,
    insertConfigurations: rawUser.config.insertConfigurations
      ? rawUser.config.insertConfigurations.map(
          (rawConfig) => {
            return {
              id: rawConfig.id,
              title: rawConfig.title,
              subtitle: rawConfig.subtitle,
              type: rawConfig.type,
              dropInConditional: rawConfig.dropInConditional
            };
          }
        )
      : undefined,
    packagingInstructions: rawUser.config.packagingInstructions
      ? rawUser.config.packagingInstructions.map(
          (rawConfig) => {
            return {
              id: rawConfig.id,
              title: rawConfig.title,
              type: rawConfig.type,
              packagingType: rawConfig.packagingType
            };
          }
        )
      : undefined
  };
}

I am now trying to accomplish the same thing but now insertConfigurations & packagingInstructions are objects and not an array. For example:

const rawTenant = {
  id: 1,
  name: "Barnes",
  config: {
    dropInConfigurations: {
        id: "TF50",
        type: "Insert",
        title: "Barnes",
        subtitle: "Welcome Booklet",
        dropInConditional: "FIRST"

    },
    packagingInstructions: {
      id: "TF50",
      type: "sticker",
      title: "Barnes",
      packagingType: "STICKER"
    }
  }
};

Because they are objects I can no longer map them as the first example. So I tried working around this but using Object.entries and then map. But I am not getting an array of undefined objects multiple times.

Here is my code snippet Object.entries :

const rawUser = {
  id: 1,
  name: "Barnes",
  config: {
    insertConfigurations: {
        id: "B22",
        type: "Insert",
        title: "Barnes",
        subtitle: "Welcome Book",
        dropInConditional: "FIRST"
    },
    packagingInstructions:{
      id: "B22",
      type: "sticker",
      title: "Barnes",
      packagingType: "STICKER"
    }
  }
};

console.log(dataReturn());

function dataReturn() {
  return {
    id: rawUser.id,
    name: rawUser.name,
    insertConfigurations: rawUser.config.insertConfigurations
      ? Object.entries(rawUser.config.insertConfigurations).map(
        ([key, rawConfig]) => {
            return {
              id: rawConfig.id,
              title: rawConfig.title,
              subtitle: rawConfig.subtitle,
              type: rawConfig.type,
              dropInConditional: rawConfig.dropInConditional
            };
          }
        )
      : undefined,
    packagingInstructions: rawUser.config.packagingInstructions
      ? Object.entries(rawUser.config.packagingInstructions).map(
        ([key, rawConfig]) => {
            return {
              id: rawConfig.id,
              title: rawConfig.title,
              type: rawConfig.type,
              packagingType: rawConfig.packagingType
            };
          }
        )
      : undefined
  };
}

How can I achieve the outcome of the first snippet when insertConfigurations & packagingInstructions are both now objects. My expected outcome is identical to the first snippet.

I expect

{
  "id": 1,
  "name": "Barnes",
  "insertConfigurations": [
    {
      "id": "B22",
      "title": "Barnes",
      "subtitle": "Welcome Book",
      "type": "Insert",
      "dropInConditional": "FIRST"
    }
  ],
  "packagingInstructions": [
    {
      "id": "B22",
      "title": "Barnes",
      "type": "sticker",
      "packagingType": "STICKER"
    }
  ]
}
1 Answers

I would start by introducing a function like convertValueWith, that can take the value and a conversion function and return either an array or object depending on the type of value.

function convertValueWith(val, conversion) {
    if (Array.isArray(val)) {
        return val.map(conversion)
    } else if (val && typeof val === 'object') {
        return [conversion(val)]
    }
}

Then you can write some conversion functions:

const insertConfigurations = (val) =>
    convertValueWith(val, (rawConfig) => {
        return {
            id: rawConfig.id,
            title: rawConfig.title,
            subtitle: rawConfig.subtitle,
            type: rawConfig.type,
            dropInConditional: rawConfig.dropInConditional
        };
    });

const packagingInstructions = (val) => 
    convertValueWith(val, (rawConfig) => {
        return {
            id: rawConfig.id,
            title: rawConfig.title,
            type: rawConfig.type,
            packagingType: rawConfig.packagingType
        };
    });

Your resulting dataReturn function becomes a bit cleaner:

function dataReturn(rawThing) {
    return {
        id: rawThing.id,
        name: rawThing.name,
        insertConfigurations: insertConfigurations(rawThing.config.insertConfigurations),
        packagingInstructions: packagingInstructions(rawThing.config.packagingInstructions),
    };
}

const rawUser = {
  id: 1,
  name: "Barnes",
  config: {
    insertConfigurations: [{
      id: "B22",
      type: "Insert",
      title: "Barnes",
      subtitle: "Welcome Book",
      dropInConditional: "FIRST"
    }],
    packagingInstructions: [{
      id: "B22",
      type: "sticker",
      title: "Barnes",
      packagingType: "STICKER"
    }]
  }
};

const rawTenant = {
  id: 1,
  name: "Barnes",
  config: {
    insertConfigurations: {
      id: "TF50",
      type: "Insert",
      title: "Barnes",
      subtitle: "Welcome Booklet",
      dropInConditional: "FIRST"
    },
    packagingInstructions: {
      id: "TF50",
      type: "sticker",
      title: "Barnes",
      packagingType: "STICKER"
    }
  }
};


function convertValueWith(val, conversion) {
  if (Array.isArray(val)) {
    return val.map(conversion)
  } else if (val && typeof val === 'object') {
    return [conversion(val)]
  }
}

const insertConfigurations = (val) =>
  convertValueWith(val, (rawConfig) => {
    return {
      id: rawConfig.id,
      title: rawConfig.title,
      subtitle: rawConfig.subtitle,
      type: rawConfig.type,
      dropInConditional: rawConfig.dropInConditional
    };
  });

const packagingInstructions = (val) =>
  convertValueWith(val, (rawConfig) => {
    return {
      id: rawConfig.id,
      title: rawConfig.title,
      type: rawConfig.type,
      packagingType: rawConfig.packagingType
    };
  });

function dataReturn(rawThing) {
  return {
    id: rawThing.id,
    name: rawThing.name,
    insertConfigurations: insertConfigurations(rawThing.config.insertConfigurations),
    packagingInstructions: packagingInstructions(rawThing.config.packagingInstructions),
  };
}

console.log(dataReturn(rawUser));
console.log(dataReturn(rawTenant));

Related