6

I have an array of objects and I want to update some of the content. I figured I could just map through the objects, find the match I was looking for and than update it.

data = data.map(obj => {
   return this.state.objToFind === obj.title;   
   }).map(obj, idx) => {
      console.log("found " + obj.title);     // reads found + undefined?
      obj.menu = this.state.menu;
      obj.title = this.state.title;
      obj.content = this.state.content;
 });

However, this is not working. I find the object but obj.anything is undefined. My console.log reads "Found undefined".

user3622460
  • 1,231
  • 5
  • 23
  • 42
  • 1
    There is **no** JSON object there: [learn what JSON really is](http://json.org) – user2864740 Oct 31 '17 at 17:47
  • I have no idea what you're trying to say. Data is an array of JSON objects. – user3622460 Oct 31 '17 at 17:48
  • 2
    If you don't understand, consider reading provided resources. – user2864740 Oct 31 '17 at 17:49
  • 1
    You're returning a boolean from the function, so the second `map()` will be processing an array of booleans, not objects. – Barmar Oct 31 '17 at 17:51
  • @user3622460 What do you want to achieve by writting `return this.state.objToFind === obj.title;`. Because this condition will return array of boolean? – Prakash Sharma Oct 31 '17 at 17:53
  • I'm trying to find the correct object to edit. I suppose I could use data.filter - find the object, delete the object and push a new object onto the array. I just thought I could edit the object directly – user3622460 Oct 31 '17 at 17:55

5 Answers5

3
data.map(obj => {
  return this.state.objToFind === obj.title;   
})

the first map will return an array of true and false, the second map will loop through these values and the console.log("found " + obj.title) will prints "found + undefined" consequently.

maybe you wanted something like this.

data = data.filter(obj => {
   return this.state.objToFind === obj.title;   
   }).map(obj, idx) => {
      console.log("found " + obj.title);
      obj.menu = this.state.menu;
      obj.title = this.state.title;
      obj.content = this.state.content;
      return obj;
 });
Karim
  • 8,454
  • 3
  • 25
  • 33
3

EVEN SIMPLER

You could use the some operator. (It works by iterating over the array, when you return true it breaks out of the loop)

data.some(function(obj){
   if (obj.title ==== 'some value'){
        //change the value here
        obj.menu = 'new menu';
        obj.title = 'new title';
        return true;    //breaks out of he loop
   }
});
Manish Poduval
  • 452
  • 3
  • 15
  • I'll check this out - this looks like what I was trying to do. I would rather not had to push and pop from the data array. – user3622460 Oct 31 '17 at 18:07
1

Change it to some other variable instead of obj since it refers to parent obj which is an array. Also use array.filter in the first function that will return an array,

data = data.filter(obj => {
   return this.state.objToFind === obj.title;   
   }).map(newval, idx) => {
      console.log("found " + newval.title);     
      newval.menu = this.state.menu;
      newval.title = this.state.title;
      newval.content = this.state.content;
 });
Sajeetharan
  • 216,225
  • 63
  • 350
  • 396
  • That's one idea but your `data` variable will just be array of undefined because your second map function doesn't return anything. – James Oct 31 '17 at 17:49
  • If I use newVal will this actually update the JSON object to these new values? I thought obj.menu would be the actually object I want to edit – user3622460 Oct 31 '17 at 17:51
  • Filter is what I had originally, but it didn't gain me anything. This will return one object and I'll have to delete the old object and push the new object onto the array. – user3622460 Oct 31 '17 at 17:56
1

Map is used to return a mutated object. When using map you need to return something back, in your case modified object.

However There are things you're doing wrong. 1) you're using .map to search something (thats not how you use map); try using .filter or .find 2) after updating your object using map (in 2nd function), you need to return it back. case 1:

data = data.filter(obj => {
       return this.state.objToFind === obj.title;   
   }).map(foundObj, idx) => {
          console.log("found " + foundObj.title);
          foundObj.menu = this.state.menu;
          foundObj.title = this.state.title;
          foundObj.content = this.state.content;
      return foundObj; //updated obj
 });

case 2:

    var foundObj = data.find(obj => {
     return this.state.objToFind === obj.title;   
   });
    console.log("found " + foundObjs.title);
    foundObjs.menu = this.state.menu;
    foundObjs.title = this.state.title;
    foundObjs.content = this.state.content;
Axar
  • 521
  • 1
  • 3
  • 11
1

If you want to process only those elements which makes this.state.objToFind === obj.title true then Array.filter is what you need like

data = data.filter(obj => {
   return this.state.objToFind === obj.title;   
   }).map(obj, idx) => {
      console.log("found " + obj.title);     // reads found + undefined?
     ...
 });
uzaif
  • 3,511
  • 2
  • 21
  • 33
Prakash Sharma
  • 15,542
  • 6
  • 30
  • 37