Search code examples
javascriptarraysreactjsuse-statereact-context

Add a new array to an object


I am using context api for state management I have set an initial state for students: null and tags: [] students is an array of objects with data like this:

[
{
 "id": 1,
 "city": "some city",
 "name" : "some name",
 "colors" : [
             "1": "blue",
             "2" : "red"
            ],
 "age": "some age"
},
{
 "id": 2,
 "city": "some city",
 "name" : "some name",
 "colors" : [
             "1": "green",
             "2" : "yellow"
            ],
 "age": "some age"
}
]

The tag array will be like this

{
 "studentId": 1,
 "tag": "some tag",
},
{
 "studentId": 2,
 "tag": "some tag",
},
{
 "studentId": 2,
 "tag": "some tag",
},
]

Now I want to add the objects in the tag array to their matching objects in student array. example, the student with id number 2, he has two tags with his id. i want the tag array with studentId 2 to be added as an array to the student object of that particular id..Dont know if i am making sense.

My state file

 const addTag = async tag => {

    try {

        dispatch({ 
            type: ADD_TAG, 
            payload: tag
           })
    } catch (error) {
        dispatch({ 
            type: STUDENT_ERROR ,
            payload: error
           })
    }
}

My reducer

 case ADD_TAG:
            return {
                ...state,
                
                tags: [...state.tags, action.payload],
 
            }

I am only populating the tags state..but i want to also do so for the students state. Thank you


Solution

  • You can simply copy the students array (so you don't mutate it directly), find the index of student object in question, and then add the tags to it.

    case ADD_TAG:
       let studentCopies = JSON.parse(JSON.stringify(state.students));
       let index = studentCopies.findIndex(s => s.id === action.payload.studentId);
    
    
       if (index > -1) {
          // if student object is in array, then add tag to student's tag array
    
         if (studentCopies[index].tags) {
           studentCopies[index].tags = [...studentCopies[index].tags, action.payload];
         } else {
            studentCopies[index].tags = [action.payload]
         }
       }  
        
    
       return {
         ...state,
         students: studentCopies,
         tags: [...state.tags, action.payload]
       }