Working with a JSON file that is not an array? Doesn't have [ ] at end and start?!

I am working with an API that doesn’t have opening [ and closing ] tags in the json file and I can not map over data.

I have created the example issue I am having here:

How could I solve this issue? Thanks, John.

I’m not sure how that link helps us help you.

JSON does not have to start with a bracket ([). It can be a curly brace ({) or just a value.

Perhaps you are incorrectly assuming that your JSON is an array? Perhaps the array you want is nested? (That has happened to me more than once.)

Do you have a link to that JSON file or can you paste in the file, at least the beginning of it?

1 Like

Hi Kevin,

Thanks for the reply.

This is the link to the json file

I want to convert it to an array so I can map over data in my react app - thanks!

If you want to map through key value pairs of the object then you may want to use Object.entries()

Yeah, you can’t literally map, as in looping over an array and creating a new element for each old element. You can get that effect by just looping over the object keys and pushing your data onto and array. Object.entries() is one way, for ... in could work too.

When in doubt, do what a developer would do - google it. Google “javascript loop over object”.


Thanks all I think I got it now :slight_smile:

Can we know the actual API you are working with? I assume the json file is just an example of one of the objects returned by the API?

What exactly are you trying to map over? Because it’s just an object of objects and there doesn’t seem to be anything to map over.

Yeah I think the backend dev has written the API correctly hence my frustration with the data.

Is basically the api - would I be wrong in saying the formatting of this API is incorrect?

Why do you think it’s incorrect? If the behavior matches the spec, it’s correct.

Yes, +1 to what Jeremy is saying.

Is it incorrect? That depends on how the API is designed. Sometimes on the front end we have to deal with APIs that don’t give the data in form that we want. Often in the API layer of my app I will just transform it into the shape that I want.

1 Like

I have no idea what the format is supposed to be. But there is nothing wrong with it.

I’m just not sure what it is you want to map over?

Ah ok thanks everyone - basically I want to map over everything and output everything all dates, text etc etc - so things like this:

If that makes sense?

So this works fine but when I try to add something like this:

Screenshot 2022-06-27 at 18.55.30

I would need to write this code:

But I get this error:

Which I do not understand why? Any suggestions? Thank you :slight_smile:

You can only map on an array. The object you have is not an array. You can may over all keys of this object, but not the object itself. You can map over a property that contains an array, but not the object itself.

Side note, a map is not a general purpose loop. A map is only for creating a new array out of the contents of an old array.

1 Like

Do you make your http request correctly and access the data only after its loaded? (Use async/promises or whatever technique you prefer/know). If you try to access “entitlement” property, before the data for “electionsSingleData” was fetched, you will run into an error.
To map the contents of an object, you could also use the for…in loop. Be careful however, it looks like the json form you work with is not very generic and while most of the data comes in the shape of objects, there also happen to be arrays and checking the type of the data, before you load it can be good idea(do something when its an array, do something else if its an object). Good way to debug and ensure you get the shape you want is to (console)log the data and slowly dig into it, until you match the good approach and wont tell you something end up being undefined or not with the expected format

If you initialize the state as an array but then try to access it as if it had properties on an object before your state is actually an object it will cause an error. Also, note that an empty array is a truthy value. So && does not protect against that.

[] && console.log('I will run')
// I will run

Your fetch code can also be simplified and as said, if you want to map the sub-properties you can use Object.entries() (or .keys()/.values())

import { useState, useEffect } from "react";
import axios from "axios";

import "./styles.css";

export default function App() {
  const [elctionsSingleData, setElectionSingleData] = useState();

  useEffect(() => {
    const getDatas = async () => {
      const res = await axios.get("");
  }, []);

  useEffect(() => {
  }, [elctionsSingleData]);

  return (
    <div className="App">
      <h2>Instrument Object.entries()</h2>
      {elctionsSingleData &&
        JSON.stringify(Object.entries(elctionsSingleData?.instrument), null, 2)}

      <hr />

      <h2>Instrument mapped</h2>
      {elctionsSingleData &&
        Object.entries(elctionsSingleData?.instrument).map(([key, value]) => (
          <div key={key}>
            <span>{key}</span>:{" "}
            <span>{value !== null ? value.toString() : "no value"}</span>

The JSON data does also have null and false as values, not as strings. If “false” is meant to be rendered to the DOM it should be a string.