Search code examples
javascriptarraysreactjsconcatenation

Only last item is added to array inside map function


I'm mapping an array inside a map function and I want to add the id of every element inside the array to a state. I'm facing an issue where just the last item is added to the array even though console log shows that the function iterates to correct number of times.

This is the code I have written

const { evc } = this.props;
evc.chargingStationGroups && evc.chargingStationGroups.map((item, key) => {
    item.stations.map((stationItem, key) => {
        console.log("stationID ",stationItem.stationID);
        var stationId = {};
        stationId = {
            stationId: stationItem.stationID
        }
        var allIdArray = this.state.stationIdArray.concat(stationId);
        this.setState({ stationIdArray: allIdArray })
    })
})

Here evc.chargingStationGroups is something like this

[
     {
      groupId: "16",
      groupName: "Sia",
      stations: [{stationId: "8", name: "Test"},{stationId: "9", name: "Test2"},{stationId: "10", name: "Test3"}]
     },
     {
      groupId: "17",
      groupName: "Maroon5",
      stations: [{stationId: "10", name: "Test"},{stationId: "11", name: "Test2"},{stationId: "10", name: "Test3"}]
     }
],

How can i add all stationItem.stationID to my array, not just the last one.


Solution

  • Only call setState once inside all your rendering (because setState is asynchronous)

    Assuming you don't have dupes of station between chargingStationGroups, just concat everybody

    const { evc } = this.props;
    if (evc.chargingStationGroups) {
        const ids = evc.chargingStationGroups.flatMap((item, key) => {
            return item.stations.map((stationItem, key) => {
                return {
                    stationId: stationItem.stationID
                }
            })
        })
        const stationIdArray = this.state.stationIdArray.concat(ids)
        this.setState({ stationIdArray })
    })
    

    Else just avoid the dupes...

    const { evc } = this.props;
    if (evc.chargingStationGroups) {
        const ids = evc.chargingStationGroups.flatMap((item, key) => {
            return item.stations.map((stationItem, key) => {
                return {
                    stationId: stationItem.stationID
                }
            })
        })
        const arr = this.state.stationIdArray.concat(ids)
        const s = new Set(arr.map(x => x.stationID))
    
        const stationIdArray = [...s].map(stationId => ({ stationId }))
        this.setState({ stationIdArray })
    })
    

    Not tested because no minimal reproducible example given, but you get the idea...