Alecbalec
Alecbalec

Reputation: 119

If object value exists in array, add to existing object

I have a function component that generates a linear chart in react based on an array of objects.

The data I'm pulling from the API looks like this:

    {
        "_id": "604face09b305032586fe235",
        "username": "Demo",
        "description": "0",
        "duration": 0,
        "date": "2021-03-15T18:52:10.749Z",
        "createdAt": "2021-03-15T18:52:16.684Z",
        "updatedAt": "2021-03-15T18:52:16.684Z",
        "__v": 0

    }

My code to generate the chart data is:

// GET Exercises
useEffect(() => {
    axios.get("http://localhost:5000/exercises")
        .then((result) => {
            setIsLoaded(true);
            setItems(result.data);
            console.log(result.data)
        })
        .catch((error) => {
            setIsLoaded(true);
            setError(error);
        })
}, [])

//  chartdata
useEffect(() => {
    const chartArray = items.map((item) => {

        const container = {};
        container.label = item.username;
        container.data = [[stripDate(item.date), item.duration]]

        return container;

    });
    setXp(chartArray);
}, [items])

However, the API could return multiple objects with "username": "Demo", what I want is that if the username value already exists in my chart data I want to update that container.data array with another array.

Current outcome:

{
    "label": "Demo",
    "data": [[15, "2021-03-15"]]
},

{
    "label": "Demo",
    "data": [[45, "2021-03-17"]]
}

What I want to achieve:

{
    "label": "Demo",
    "data": [[15, "2021-03-15"], [45, "2021-03-17"]]
}

Any help or guidance is appreciated.

Upvotes: 0

Views: 83

Answers (1)

Hassan Imam
Hassan Imam

Reputation: 22524

You need to group your data based on the username value using array#reduce in an object accumulator. For repeated username push new data in the array. Then get the values from this accumulator using Object.values().

useEffect(() => {
  const chartArray = Object.values(items.reduce((r, o) => {
    r[o.username] = r[o.username] || { label: o.username, data: []};
    r[o.username].data.push([o.duration, stripDate(o.date)]);
    return r;
  },{}));
  setXp(chartArray);
}, [items])

Upvotes: 1

Related Questions