Bishan
Bishan

Reputation: 15740

Get data from Array in JSON Object

I need to get the timestamp of the object where new_name in status_change is Solved.

I have tried this.

console.log(
 ticket.updates ? 
 (
  (ticket.updates.find(x => x.status_change !== null) && 
   ticket.updates.find(x => x.status_change !== null).status_change.new_name === 'Solved') ?
  ticket.updates.find(x => x.status_change !== null).timestamp : 
   'new_name is ' + ticket.updates.find(x => x.status_change !== null).status_change.new_name
 ) 
 : 'No updates');

But above code didn't give the expected result.

Here is my data set.

{
    "updates": [{
            "timestamp": "2018-04-26 06:39:12",
            "by": {
                "name": "A1"
            },
            "status_change": {
                "new_name": "Open",
                "old_name": null
            }
        }, {
            "timestamp": "2018-04-27 00:09:44",
            "by": {
                "name": "B1"
            },
            "status_change": null
        }, {
            "timestamp": "2018-04-27 00:10:09",
            "by": {
                "name": "B1"
            },
            "status_change": {
                "new_name": "Solved",
                "old_name": "Open"
            }
        }
    ]
}

What could be the issue? JSFiddle

Upvotes: 1

Views: 76

Answers (6)

Viacheslav aka Lord
Viacheslav aka Lord

Reputation: 180

Perhaps the most stupid, but IMHO the simplest solution:

var ticket = {"updates":[{"timestamp":"2018-04-26 06:39:12","by":{"name":"A1"},"status_change":{"new_name":"Open","old_name":null}},{"timestamp":"2018-04-27 00:09:44","by":{"name":"B1"},"status_change":null},{"timestamp":"2018-04-27 00:10:09","by":{"name":"B1"},"status_change":{"new_name":"Solved","old_name":"Open"}}]};

for (var i in ticket.updates ) {
    var item=ticket.updates[i];
    if (typeof item.status_change === 'object' && item.status_change !== null) {
             if (item.status_change.new_name === 'Solved') {
                    alert('Found timestamp value: ' + item.timestamp);
             }
    }
}

Upvotes: 0

cнŝdk
cнŝdk

Reputation: 32165

Well instead of using .find() in your conditions, you better use .some() which is made for this, and also you can use only one .some() call to group all of these conditions.

And instead of writing x.status_change != null you can just write x.status_change, which gives the same result.

console.log(
    ticket.updates ?
      ticket.updates.some(x => x.status_change && x.status_change.new_name === 'Solved') ?
        ticket.updates.find(x => x.status_change && x.status_change.new_name === 'Solved').timestamp :
        'new_name is ' + ticket.updates.find(x => x.status_change).status_change.new_name
      : 'No updates');

Demo:

let ticket = {
  "updates": [{
    "timestamp": "2018-04-26 06:39:12",
    "by": {
      "name": "A1"
    },
    "status_change": {
      "new_name": "Open",
      "old_name": null
    }
  }, {
    "timestamp": "2018-04-27 00:09:44",
    "by": {
      "name": "B1"
    },
    "status_change": null
  }, {
    "timestamp": "2018-04-27 00:10:09",
    "by": {
      "name": "B1"
    },
    "status_change": {
      "new_name": "Solved",
      "old_name": "Open"
    }
  }]
};


console.log(
    ticket.updates ?
      ticket.updates.some(x => x.status_change && x.status_change.new_name === 'Solved') ?
        ticket.updates.find(x => x.status_change && x.status_change.new_name === 'Solved').timestamp :
        'new_name is ' + ticket.updates.find(x => x.status_change).status_change.new_name
      : 'No updates');

Upvotes: 1

Tornike Shavishvili
Tornike Shavishvili

Reputation: 1354

The code below will do what you have asked. solvedData will contain timestamp of the objects, in which status_change is Solved. See code below. Feel free for any question.

var myData = {
    "updates": [{
            "timestamp": "2018-04-26 06:39:12",
            "by": {
                "name": "A1"
            },
            "status_change": {
                "new_name": "Open",
                "old_name": null
            }
        }, {
            "timestamp": "2018-04-27 00:09:44",
            "by": {
                "name": "B1"
            },
            "status_change": null
        }, {
            "timestamp": "2018-04-27 00:10:09",
            "by": {
                "name": "B1"
            },
            "status_change": {
                "new_name": "Solved",
                "old_name": "Open"
            }
        }
    ]
};

var solvedData = [];

var i=0;
if(myData.updates){
    for(i=0;i<myData.updates.length; i++){
        if(myData.updates[i].status_change && myData.updates[i].status_change.new_name === "Solved"){
            solvedData.push(myData.updates[i].timestamp);
        }
    }
}

  for(i=0;i<solvedData.length; i++){
    console.log(solvedData[i]);
  }

Upvotes: 0

Panos K
Panos K

Reputation: 1091

this should work

  • filtering the existing status_change
  • filtering new_name === "Solved"
  • mapping timestamps

const tickets = {
  "updates": [{
    "timestamp": "2018-04-26 06:39:12",
    "by": {
      "name": "A1"
    },
    "status_change": {
      "new_name": "Open",
      "old_name": null
    }
  }, {
    "timestamp": "2018-04-27 00:09:44",
    "by": {
      "name": "B1"
    },
    "status_change": null
  }, {
    "timestamp": "2018-04-27 00:10:09",
    "by": {
      "name": "B1"
    },
    "status_change": {
      "new_name": "Solved",
      "old_name": "Open"
    }
  }]
};
console.log(tickets.updates
  .filter(x => x.status_change && x.status_change.new_name === "Solved")
  .map(x => x.timestamp));

Upvotes: 0

Anand Undavia
Anand Undavia

Reputation: 3543

You can first use .filter() to filter out the not required objects. And then use .map() to get the necessary fields.

Here is how:

const data = {
    "updates": [{
            "timestamp": "2018-04-26 06:39:12",
            "by": {
                "name": "A1"
            },
            "status_change": {
                "new_name": "Open",
                "old_name": null
            }
        }, {
            "timestamp": "2018-04-27 00:09:44",
            "by": {
                "name": "B1"
            },
            "status_change": null
        }, {
            "timestamp": "2018-04-27 00:10:09",
            "by": {
                "name": "B1"
            },
            "status_change": {
                "new_name": "Solved",
                "old_name": "Open"
            }
        }
    ]
}

const timestamps = data.updates
  .filter(x => x.status_change && x.status_change.new_name === 'Solved')
  .map(x => x.timestamp);

if(timestamps.length >= 1) {
  console.log('updates:', timestamps);
} else {
  console.log('no updates');
}

Upvotes: 1

Mark
Mark

Reputation: 92461

You can use more than one boolean in find() to short-circuit it so you don't need the repeated find() calls:

let obj = {"updates": [{"timestamp": "2018-04-26 06:39:12","by": {"name": "A1"},"status_change": {"new_name": "Open","old_name": null}}, {"timestamp": "2018-04-27 00:09:44","by": {"name": "B1"},"status_change": null}, {"timestamp": "2018-04-27 00:10:09","by": {"name": "B1"},"status_change": {"new_name": "Solved","old_name": "Open"}}]}

let item = obj.updates.find(item => 
   item.status_change
   && item.status_change.new_name == "Solved")

if (item) { // found one
  console.log(item.timestamp)
} else {   // not found
  console.log("no new items")
}

Upvotes: 1

Related Questions