Home > OS >  how to transform json properties to multiple objects with key value (typescript react)
how to transform json properties to multiple objects with key value (typescript react)

Time:11-16

i'm trying to use fetched data form an api in a recharts linechart but i'm having trouble mapping the json data. i have an api that return data as shown below, basically count of predictions in each month and 0 if the month doesnt exist but the data is in a format that i can't map through it. i have a single object in the json data and would like to transform it to multiple objects using key as a value for another key and value as another value for another key. sorry for my bad explanation i don't know how to describe this problem.

data format

[
  {
    "_id": 2022,
    "jan": 1,
    "feb": 0,
    "mar": 0,
    "apr": 0,
    "may": 0,
    "jun": 0,
    "jul": 0,
    "aug": 0,
    "sep": 0,
    "oct": 0,
    "nov": 13,
    "dec": 0
  }
]

format that i want to achieve to use in a state

[
  {
    "month": "jan",
    "count": 1
  },
  {
    "month":"feb",
    "count":"0"
  },
  {
    "month":"mar",
    "count":"0"
  }
  {
    "month":"apr",
    "count":"0"
  },
  {
    "month":"may",
    "count":"0"
  }
}

i would like to skip the year aswell

linechart code

import React, { useEffect, useState } from "react";
import {
    LineChart,
    XAxis,
    YAxis,
    CartesianGrid,
    Line,
    Tooltip,
    Legend
} from 'recharts';

const PredictionsMonthLinechart = () => {
    const [d, setD] = useState([
        {
            month: 'jan',
            predictions: 4000,
        },
    ])

    const fetchData = async () => {
        const res = await fetch("http://localhost:5000/query/predictions_per_month");
        const data = await res.json()
            .then(data => {
                setD((Object.keys(data)).map((key) => {
                    return {
                        month: key,
                        predictions: data[key]
                    }
                }))
            })
        console.log(data);
        console.log(d);
    }

    useEffect(() => {

        fetchData();
    }, []);


    return (
        <LineChart width={1100} height={400} data={d}
            margin={{ top: 5, right: 30, left: 20, bottom: 5 }}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="month" />
            <YAxis />
            <Tooltip />
            <Legend />
            <Line type="monotone" dataKey="predictions" stroke="#8884d8" />

        </LineChart>
    )
}

export default PredictionsMonthLinechart;

i have tried using Object.entries() but it keeps giving me errors in IDE Object.keys() returns undefined object but atleast it's reading the keys correctly.

Uncaught Error: Objects are not valid as a React child (found: object with keys {\_id, jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec}). If you meant to render a collection of children, use an array instead.

CodePudding user response:

Assuming that data that you get from the request is (as you said):

[
  {
    "_id": 2022,
    "jan": 1,
    "feb": 0,
    "mar": 0,
    "apr": 0,
    "may": 0,
    "jun": 0,
    "jul": 0,
    "aug": 0,
    "sep": 0,
    "oct": 0,
    "nov": 13,
    "dec": 0
  }
]

Then this line can't be correct because data is an array, not an object:

setD((Object.keys(data)).map((key) => {

Adapting the code to this should make it compile (it also contains a filter for the year property):

.then(data => {
  setD((Object.keys(data[0])).filter(key => key !==  "_id").map((key) => {
    return {
      month: key,
      predictions: data[0][key]
    }
  }))
})
  • Related