Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object Push into Array within For Loop/For Each Loop is causing duplicates

I would like to give each object in my Array a property that corresponds to an ID. I've tried this every possible way it seems like, below is the latest.

When I console.log the output individually it all looks good. However, when I run the output.push() and then log output, there are duplicates.

I found the below post which seems very similiar but after applying the changes suggested, I am still facing the same issue--In that I am seeing repeating IDs in the final output. The IndexID property is not unique and it should be for each iteration.

React object property value being duplicated on .push inside loop

Simple example first, then actual code example:

   flattenedWorkouts.forEach((currAlias,index) =>{
       
        const obj ={}
        const newMemberAttributes = Object.assign(obj, { alias: currAlias });
        newMemberAttributes.alias.indexID= index
                     
            console.log("memberAttributes:", newMemberAttributes);
         
            output.push(newMemberAttributes.alias)
    
    })

Snippet of the FlattenedWorkout elements that are incorrect...there are 100 so not including all + i've trimmed down the object:

  Array [
      Object {
        "Round": "AMRAP 1",
        "indexID": 6,
   
      },
  Object {
        "Round": "AMRAP 1",
        "indexID": 6,
   
      },
  Object {
        "Round": "AMRAP 1",
        "indexID": 6,
   
      },

What I would expect to see:

 Object {
        "Round": "AMRAP 1",
        "indexID": 6,
   
      },
  Object {
        "Round": "AMRAP 1",
        "indexID": 7,
   
      },
  Object {
        "Round": "AMRAP 1",
        "indexID": 8,
   
      },

Actual Issue. Below is the starting Object.

var WorkoutDetail = [
  //Dummy item to act as begin of carasoul
  {
    RoundID: 1,
    Round: 'AMRAP 1',
    NumberOfSets: 3,
    Activity: [{
        key: '1',
        title: 'AMRAP 1',
        description: "Banded curtsy lunge to side leg raise",
      },
      {
        key: '2',
        title: 'AMRAP 1',
        description: "Inchworm with push-up",
      },
      {
        key: '3',
        title: 'AMRAP 1',
        description: "Static lunge with single arm press",
      }
    ]
  },

  {
    RoundID: 2,
    Round: 'AMRAP 2',
    NumberOfSets: 2,
    Activity: [{
        key: '4',
        title: 'AMRAP 2',
        description: "Side plank to leg extension",
      },
      {
        key: '5',
        title: 'AMRAP 2',
        description: "Burpee to bench jump",
      },
      {
        key: '6',
        title: 'AMRAP 2',
        description: "Banded heel tap jump squat",
      }
    ]
  },
  {
    RoundID: 3,
    Round: 'AMRAP 3',
    NumberOfSets: 1,
    Activity: [{
        key: '7',
        title: 'AMRAP 3',
        description: "Weighted pike plank",
      },
      {
        key: '8',
        title: 'AMRAP 3',
        description: "Incline push up",
      },
      { //Dummy item to make as caboose
        key: '9',
        title: 'AMRAP 3',
        description: "Weighted pike plank",
      },
      //Dummy item to make as caboose in carasoul
    ]
  }
]

// Next a Method I am using to loop over this object and * flatten * it out:

var FlatWorkoutDetail = () => {
  var flattenedWorkouts = []
  var iterationNumber = 0

  //Each Round
  WorkoutDetail.forEach(x => {

    for (let i = 1; i <= x.NumberOfSets; i++) {
    
      for (let a = 0; a < x.Activity.length; a++) {
        var obj = x.Activity[a]
        obj.Round = x.Round
        obj.SetNumber = i
        flattenedWorkouts.push(obj)
        iterationNumber++;
      }
    }
  })

  return flattenedWorkouts
}

// Simple forEach Solution:
var FlatWorkoutDetailOutput = (val) => {
  val.forEach((obj, i) => obj.indexID = i);
}

// Execute the functions:
const TestArray = FlatWorkoutDetail()
const TestArray2 = FlatWorkoutDetailOutput(TestArray)

console.log(TestArray);

Final output is incorrect. 6 is the starting index and 14 is repeated twice:

Array [
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Banded curtsy lunge to side leg raise",
    "image": null,
    "indexID": 6,
    "key": "1",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Test.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Inchworm with push-up",
    "image": null,
    "indexID": 7,
    "key": "2",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout3.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Static lunge with single arm press",
    "image": null,
    "indexID": 8,
    "key": "3",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Banded curtsy lunge to side leg raise",
    "image": null,
    "indexID": 6,
    "key": "1",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Test.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Inchworm with push-up",
    "image": null,
    "indexID": 7,
    "key": "2",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout3.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Static lunge with single arm press",
    "image": null,
    "indexID": 8,
    "key": "3",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Banded curtsy lunge to side leg raise",
    "image": null,
    "indexID": 6,
    "key": "1",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Test.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Inchworm with push-up",
    "image": null,
    "indexID": 7,
    "key": "2",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout3.mp4",
  },
  Object {
    "Round": "AMRAP 1",
    "SetNumber": 3,
    "description": "Static lunge with single arm press",
    "image": null,
    "indexID": 8,
    "key": "3",
    "time": " 45 Seconds",
    "title": "AMRAP 1",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 2",
    "SetNumber": 2,
    "description": "Side plank to leg extension",
    "image": null,
    "indexID": 12,
    "key": "4",
    "time": " 45 Seconds",
    "title": "AMRAP 2",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 2",
    "SetNumber": 2,
    "description": "Burpee to bench jump",
    "image": null,
    "indexID": 13,
    "key": "5",
    "time": " 45 Seconds",
    "title": "AMRAP 2",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 2",
    "SetNumber": 2,
    "description": "Banded heel tap jump squat",
    "image": null,
    "indexID": 14,
    "key": "6",
    "time": " 45 Seconds",
    "title": "AMRAP 2",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 2",
    "SetNumber": 2,
    "description": "Side plank to leg extension",
    "image": null,
    "indexID": 12,
    "key": "4",
    "time": " 45 Seconds",
    "title": "AMRAP 2",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 2",
    "SetNumber": 2,
    "description": "Burpee to bench jump",
    "image": null,
    "indexID": 13,
    "key": "5",
    "time": " 45 Seconds",
    "title": "AMRAP 2",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 2",
    "SetNumber": 2,
    "description": "Banded heel tap jump squat",
    "image": null,
    "indexID": 14,
    "key": "6",
    "time": " 45 Seconds",
    "title": "AMRAP 2",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 3",
    "SetNumber": 1,
    "description": "Weighted pike plank",
    "image": null,
    "indexID": 15,
    "key": "7",
    "time": " 45 Seconds",
    "title": "AMRAP 3",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 3",
    "SetNumber": 1,
    "description": "Incline push up",
    "image": null,
    "indexID": 16,
    "key": "8",
    "time": " 45 Seconds",
    "title": "AMRAP 3",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
  Object {
    "Round": "AMRAP 3",
    "SetNumber": 1,
    "description": "Weighted pike plank",
    "image": null,
    "indexID": 17,
    "key": "9",
    "time": " 45 Seconds",
    "title": "AMRAP 3",
    "video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
  },
]
like image 908
BoolinBov Avatar asked May 26 '26 10:05

BoolinBov


1 Answers

I don't know what else is going on in your code, but you're mutating the initial object a lot. Mutation is the source of all evil, try to avoid it like COVID.

Do this, it should solve your index problem.

var FlatWorkoutDetailOutput = (val) =>{
                              // shallow copy of the object, it only works cause the object is flat
  return val.map((obj, i) => ({...obj, indexID: i}));

}

Now TestArray will have the same bug as before, but TestArray2 will have the correct indexID.

As a rule of thumb, every time you want an object to look differently than it originally was, create a new object based on the original one. If you have an array of objects, use map and return a new array with new objects based on the original objects.

So in your previous code instead of doing this

var obj = x.Activity[a]
obj.Round =  x.Round
obj.SetNumber = i
flattenedWorkouts.push(obj)
iterationNumber ++;

do this

var originalObj = x.Activity[a]
var newObj = { ...originalObj } // this is a shallow copy, if you want to copy deep nested objects look up some library
newObj.SetNumber = i
flattenedWorkouts.push(newObj)
iterationNumber ++;
like image 81
shidoro Avatar answered May 28 '26 00:05

shidoro