Rohit Gupta
Rohit Gupta

Reputation: 55

convert nested object to one level up object in javascript

given json : -

{
    "_id": "5c1c4b2defb4ab11f801f30d",
    "name": "Ray15",
    "email": "[email protected]",
    "deviceToken": "dgtssgeegwes",
    "deviceType": "IOS",
    "tokens": [
        {
            "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YzFjNGIyZGVmYjRhYjExZjgwMWYzMGQiLCJhY2Nlc3MiOiJhdXRoIiwiaWF0IjoxNTQ1MzU4MTI2fQ.YdK0MjOm7Lff22uTFITQdic0gKdMZRpsmRee-yejDpQ"
        }
    ]
}

desired json: -

{
  "_id": "5c1c4b2defb4ab11f801f30d",
  "name": "Ray15",
  "email": "[email protected]",
  "deviceToken": "dgtssgeegwes",
  "deviceType": "IOS",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YzFjNGIyZGVmYjRhYjExZjgwMWYzMGQiLCJhY2Nlc3MiOiJhdXRoIiwiaWF0IjoxNTQ1MzU4MTI2fQ.YdK0MjOm7Lff22uTFITQdic0gKdMZRpsmRee-yejDpQ"
}

I want to convert JSON with the help of lodash library of npm in javascript or suggest any other library,

it might be a silly question, Please explain it properly, I am a newbie in javascript and try to learn node.js. comment me if you need more explanation.

Thanks for help

Upvotes: 0

Views: 2800

Answers (3)

Jug
Jug

Reputation: 304

There are a number of ways to solve this problem and no one "right" way. However, you may want to consider creating a new object, rather than mutating the original object. Objects are always passed by reference in JavaScript and it's easy to accidentally modify an object inside a function, not realizing that you just changed that object everywhere else it's referenced as well.

Since you mentioned it, here is a way to solve this with Lodash.

const obj = {
    "_id": "5c1c4b2defb4ab11f801f30d",
    "name": "Ray15",
    "email": "[email protected]",
    "deviceToken": "dgtssgeegwes",
    "deviceType": "IOS",
    "tokens": [
        {
            "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YzFjNGIyZGVmYjRhYjExZjgwMWYzMGQiLCJhY2Nlc3MiOiJhdXRoIiwiaWF0IjoxNTQ1MzU4MTI2fQ.YdK0MjOm7Lff22uTFITQdic0gKdMZRpsmRee-yejDpQ"
        }
    ]
};

// create a new object without the tokens property
const newObj = _.omit(obj, 'tokens');

// get the first token object from the tokens array
const tokenObj = _.head(obj.tokens);

// get the token string from the token object, defaulting to empty string if not found
newObj.token = _.get(tokenObj, 'token', '');

console.log(newObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Lodash is a great library and used by many projects. It can be especially helpful for new developers. For example, _.head(arr) will return undefined if arr is undefined. However, arr[0] would crash in the same scenario.

Here's one way to solve it without a library.

const obj = {
    "_id": "5c1c4b2defb4ab11f801f30d",
    "name": "Ray15",
    "email": "[email protected]",
    "deviceToken": "dgtssgeegwes",
    "deviceType": "IOS",
    "tokens": [
        {
            "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YzFjNGIyZGVmYjRhYjExZjgwMWYzMGQiLCJhY2Nlc3MiOiJhdXRoIiwiaWF0IjoxNTQ1MzU4MTI2fQ.YdK0MjOm7Lff22uTFITQdic0gKdMZRpsmRee-yejDpQ"
        }
    ]
};

// create a copy of the original object.
// note that Object.assign will make a shallow copy of our object,
// so newObj.tokens will be a pointer to obj.tokens.
// in this instance, we don't care, as we are going to remove newObj.tokens anyway.
const newObj = Object.assign({}, obj);

// throw away the tokens property.
// OK to mutate newObj as we know it is not used anywhere else.
delete newObj.tokens;

// get the first token object from the tokens array.
// the (expectedArray || []) pattern ensures we have an array if obj.tokens is null or undefined.
const tokenObj = (obj.tokens || [])[0];

// get the token string from the token object.
// again, using the (expectedObject || {}) pattern in case tokenObj is null or undefined.
const token = (tokenObj || {}).token;

// create a new property called "token" on our newObj object.
// set it to our token value or an empty string if token is null or undefined.
newObj.token = token || '';

// of course, if you know the tokens array will always have a valid token object,
// you can simply use newObj.token = obj.tokens[0].token.

console.log(newObj);

Upvotes: 0

Mulan
Mulan

Reputation: 135406

Using destructuring assignment with "empty" representations of your types works nicely. transform produces a reliable output when tokens contains zero, one, or many { token: ... } values.

const emptyUser =
  { _id: 0, name: "", tokens: [] }
  
const emptyToken =
  { token: "" }

const toSingleTokenUser =
  ({ tokens: [ { token } = emptyToken ], ...u } = emptyUser) =>
    ({ ...u, token })

console .log
  ( toSingleTokenUser ({ _id: 1, name: "a", tokens: [ { token: "t" } ] })
    // { _id: 1, name: "a", token: "t" }
    
  , toSingleTokenUser ({ _id: 1, name: "a", tokens: [] })
    // { _id: 1, name: "a", token: "" }
    
  , toSingleTokenUser ({ _id: 1, name: "a", tokens: [ { token: "t1" }, { token: "t2" } ] })
    // { _id: 1, name: "a", token: "t1" }

  , toSingleTokenUser ({ foo: "bar", tokens: [ { token: "t" } ] })
    // { foo: "bar", token: "t" }
  )

Upvotes: 0

Mark
Mark

Reputation: 92461

You don't really need a library, you can just assign the property and delete the other.

However tokens is an array, which suggest there might be more than one. This will only take the first one (obj.tokens[0].token). Since objects can't have duplicate keys, you will only be able to have one token with your desired format (if that matters).

let obj = {
    "_id": "5c1c4b2defb4ab11f801f30d",
    "name": "Ray15",
    "email": "[email protected]",
    "deviceToken": "dgtssgeegwes",
    "deviceType": "IOS",
    "tokens": [
        {
            "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YzFjNGIyZGVmYjRhYjExZjgwMWYzMGQiLCJhY2Nlc3MiOiJhdXRoIiwiaWF0IjoxNTQ1MzU4MTI2fQ.YdK0MjOm7Lff22uTFITQdic0gKdMZRpsmRee-yejDpQ"
        }
    ]
}

obj.token = obj.tokens[0].token 
delete obj.tokens
console.log(obj)

Upvotes: 1

Related Questions