How do i iterate over JSON data in React - javascript

What i'm trying to do:
Have some practice with fetching data in react, and i used a covid19 api with number of cases etc...
Here's the code :
import { useState, useEffect } from "react";
import axios from "axios";
const Home = () => {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios("api_here",);
setData([result.data]);
};
fetchData();
}, [])
console.log(data);//i have a screen-shot below for the output
return (
<ul>
{data.map((items, index) => (
<li key={index}>{JSON.stringify(items)}</li>
//<li key={index}>{items}</li> This doesn't work
))}
</ul>
)} export default Home;
The problem is that the data is an array of 1 element, image here:
And data.map is iterating only on json[0] but i need to iterate over every country from the json.
I tried doing something like :
setData([result.data][0])
//or
data[0].map......
But doesn't work
A picture with the json data:

Your data is a map of key -> value so to iterate over all countries (keys).
<ul>
{Object.keys(data).map((key, index) => (
<li key={index}>{JSON.stringify(data[key])}</li>
))}
</ul>

You can Convert the Object of Objects to Array of Objects.
import { useState, useEffect } from "react";
import axios from "axios";
const Home = () => {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios("api_here",);
let res = [result.data];
res = Object.entries(res[0]).map((e) => ( { [e[0]]: e[1] } ));
setData(res);
};
fetchData();
}, [])
console.log(data);
return (
<ul>
{data.map((items, index) => (
<li key={index}>{JSON.stringify(items)}</li>
//<li key={index}>{items}</li> This doesn't work
))}
</ul>
)} export default Home;

Related

why I can't fetch product title from fakestore api? [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 7 months ago.
I want to fetch product title from fakestoreapi . but why product title shows undefined in console.
Here is my code -
import React, { useEffect, useState } from "react";
import axios from "axios";
const Ari = () => {
const [name, setName] = useState([]);
useEffect(() => {
async function getData() {
const res = await axios.get(
"https://fakestoreapi.com/products"
);
setName(res);
console.log(res.data.title);
}
getData();
}, []);
return <>
<h1>nothing to show now</h1>
</>;
};
export default Ari;
if you get api from axios you will receive a data of array. and you must access with console.log(res.data[indexOfArrayData].title).
see this code for resolve your problem.
const GetDataAxios = () => {
const [data, setData] = useState([]);
useEffect(() => {
getData();
}, []);
const getData = async () => {
const res = await axios.get("https://fakestoreapi.com/products");
setData(res.data);
console.log(res.data[1].title)
};
return (
<div>
{data &&
data.map((item, i) => (
<div key={i}>
<p>{item.title}</p>
</div>
))}
</div>
);
};

How to get data using async await?

How to get the data correctly
import { NextApiHandler } from "next";
import data from "../../../lib/data.json";
const cars: NextApiHandler = (_req, res) => {
res.status(200).json(data);
};
export default cars;
I tried to use async await for getting data but something went wrong. When I`m trying to print in console.log what is "cars" it returns me function instead of promise.
You can try this way to get data
import React, { useEffect, useState } from 'react';
import Item from '../Item/Item';
const Items = () => {
const [items, setItems] = useState([]);
useEffect( ()=>{
fetch('http://localhost:5000/items')
.then(res => res.json())
.then(data => setItems(data));
}, [])
return (
<div id='items' className='container'>
<h1 className='item-title'>Items For You</h1>
<div className="items-container">
{
items.map(item => <Item
key={item._id}
item={item}
>
</Item>)
}
</div>
</div>
);
};
export default Items;

Trouble displaying the data from an api

So, this a weird problem. Yesterday everything was working fine, I could see the category object displayed, I could switch between categories, but today I wanted to continue the project, but the data is not being displayed, I can not even see the object in the console. What could be the problem, is it in the Fetch I would really really appreciate the help
import React, {useState, useEffect} from 'react'
import URL from '../utilis/URL'
const BookContext = React.createContext();
export default function BooksProvider({ children }) {
const [data, setData] = useState([])
const [currentSelectedCategory, setCurrentSelectedCategory] = useState([]);
const handleSelectCategory = (category) => {
setCurrentSelectedCategory(data[category]);
};
const fetchData = async () => {
const response = await fetch(URL);
const result = await response.json();
console.log(data.result)
setCurrentSelectedCategory(result[Object.keys(result)[0]]);
setData(data);
};
useEffect(()=>{
fetchData();
},[])
return (
<BookContext.Provider value={{ data, handleSelectCategory, setCurrentSelectedCategory, currentSelectedCategory }}>
{children}
</BookContext.Provider>
);
}
export {BookContext, BooksProvider}
import React,{useState, useEffect} from 'react'
import './Home.css'
import Books from './Books'
import { BookContext } from "../../context/books";
const Home = () => {
const {data, handleSelectCategory, currentSelectedCategory } =React.useContext(BookContext)
return (
<div className='books__container' >
<h1 className='categories'>Categories</h1>
{Object.keys(data).map((key, index)=>{
let books = data[key];
return (
<>
<span key={key} onClick={() => handleSelectCategory(key)} className='books__list' >
{books[0].category}
</span>
</>
);})}
<Books category={currentSelectedCategory} />
</div>
)
}
export default Home
This doesn't do anything:
console.log(data.result)
Because data is an empty array (and arrays have no result property anyway):
const [data, setData] = useState([])
And this doesn't do anything:
setData(data);
Because you're just updating the state to itself, which changes nothing and probably doesn't trigger any re-render. (Though even if it does, the render is mapping the elements of data which is still an empty array.)
You probably meant to set the data state object to the result from the API?:
setData(result);

Rendering info from the Reddit API using React

I am trying to build a basic web app where a user can search for subreddits using the Reddit API.
However, while I can console.log the data I need from the API I cannot seem to figure out how to display it.
import React, { useState, useEffect } from "react";
import Amplify, { API, graphqlOperation } from "aws-amplify";
import aws_exports from "./aws-exports";
import { withAuthenticator, AmplifySignOut } from '#aws-amplify/ui-react';
import awsconfig from "./aws-exports";
import './App.css'
import axios from 'axios'
import CharacterGrid from './components/CharacterGrid'
import SearchBar from './components/SearchBar'
Amplify.configure(awsconfig);
const App = () => {
const [items, setItems] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [query, setQuery] = useState('')
useEffect(() => {
const fetchItems = async () => {
setIsLoading(true)
const result = await axios(
`https://www.reddit.com/subreddits/search.json?q=${query}`
)
setItems(result.data)
setIsLoading(false)
}
fetchItems()
}, [query])
return (
<div className='container'>
<AmplifySignOut/>
<SearchBar style={{ marginTop: "6%" }} getQuery={(q) => setQuery(q)} />
<CharacterGrid isLoading={isLoading} items={items} />
</div>
)
}
export default withAuthenticator(App)
The child component CharacterGrid looks like this:
import React from 'react'
import CharacterItem from './CharacterItem'
const CharacterGrid = ({items, isLoading}) => {
return
isLoading
? (<h1>Loading ...</h1>)
: (
<section className='cards'>
<p>{items.data}</p> //this does not work
<p>{items.children}</p> //this does not work either
</section>
)
}
export default CharacterGrid
All I want to do is show the names of the subreddits that are returned from the API for the query string the user enters. Where am I going wrong? I have also tried converting to JSON, and mapping through the responses using .map() but I keep getting errors no matter what I try. Where am I going wrong?
However, while I can console.log the data I need from the API I cannot seem to figure out how to display it.
Because Reddit API returns an array of subreddits you should use map() function to iterate over the array and convert each item into React element.
items.map(i => (
<li key={i.data.display_name_prefixed}>
{i.data.display_name}
</li>
))
All I want to do is show the names of the subreddits that are returned from the API for the query string the user enters.
You need to inspect the data schema yourself and scrape the response properly.
Here is working example:
const { useState, useEffect } = React;
const App = () => {
const [items, setItems] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [query, setQuery] = useState("");
useEffect(() => {
setIsLoading(true);
if (query.length >= 3) {
axios(`https://www.reddit.com/subreddits/search.json?q=${query}`)
.then(response => setItems(response.data.data.children))
.catch(error => console.log("Error", error));
}
setIsLoading(false);
}, [query]);
return (
<div>
<input type="text" value={query} onChange={e => setQuery(e.target.value)} />
<CharacterGrid items={items} isLoading={isLoading} />
</div>
);
}
const CharacterGrid = ({ items, isLoading }) => {
return isLoading ? (
<h1>Loading ...</h1>
) : (
<ul>
{items.map(i => (
<li key={i.data.display_name_prefixed}>
{i.data.display_name} ({i.data.display_name_prefixed})
</li>
))}
</ul>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<div id="root"></div>
In order to loop through the elements and e.g: print the title, you could do the following.
items.data.children.map(child => <p> child.data.title </p>)
According to the response provided by reddit,
reddit response

Map is not defined

I keep getting this error that map is not defined. I changed my code around because of a regeneratorRuntime error and now I'm stuck with this one. Any help is appreciated!
import React, {Component, useEffect, useState} from 'react'
import axios from 'axios'
require("regenerator-runtime/runtime");
const App = () => {
const [data, setData] = useState({heroes: []});
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://api.opendota.com/api/heroStats',
);
setData(result.data);
};
fetchData();
}, []);
return(
<ul>
{data.heroes.map(item => (
<li key={item.id}>
<a href={item.name}>{item.localized_name}</a>
</li>
))}
</ul>
)
};
export default App
Define like this
setData({...data, heroes:result.data});
because you have pass heroes array variable to state so spread variable then set data
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://api.opendota.com/api/heroStats',
);
setData({...data, heroes:result.data});
};
fetchData();
}, []);
The data returned from that API is just an array of objects. There is no key 'heroes'. So just do: data.map(item =>... and you should be good.
it'll working:
import React, {Component, useEffect, useState} from 'react'
import axios from 'axios'
require("regenerator-runtime/runtime");
const App = () => {
const [data, setData] = useState({heroes: []});
useEffect(() => {
// Using an IIFE
( async () => {
const result = await axios(
'https://api.opendota.com/api/heroStats',
);
setData({...data, heroes: result.data || [] });
})();
}, []);
return(
<ul>
{data.heroes.map(item => (
<li key={item.id}>
<a href={item.name}>{item.localized_name}</a>
</li>
))}
</ul>
)
};
export default App
{data.heroes && data.heroes.map(item => (...
Will this work?
The .map function is only available on array.
Check what type "data" is being set to, and make sure that it is an array.
Here, the heros data is not set to "data" so you need to add to "Data"
you can do by using setData({...data, heroes:result.data});
this will work for you!

Categories

Resources