cant access an obj in multidimensional array - arrays

import axios from "axios";
import { useState, useEffect } from "react";
import "./styles.css";
export default function App() {
let [data, setdata] = useState([]);
const update = async () => {
try {
await axios
.get("https://mocki.io/v1/94d0cd81-ed46-4db6-9304-c5e119bcf334")
.then((res) => {
setdata(res.data);
console.log(data);
});
} catch (error) {
console.log(error);
}
};
useEffect(() => {
update();
}, []);
return (
<div className="App">
{data.map((e) => {
return (
<>
<h1>{e.number[0].school}</h1>
</>
);
})}
<button onClick={update}>click me</button>
</div>
);
}
can someone help me so solve this problem, please?
i am trying to display the number's obj, but i cant.
its not the real one, but i make it as similar as the real one.
any help will be appreciated.
thankyou

Related

Dynamically setting the state is not working in react

I am trying to set an array dynamically and render it using useState hook. But it seems the array is not setting. below is my code:
import React, { useState, useEffect } from "react";
export default ({ item }) => {
const [attachments, setAttachments] = useState([]);
const setAttachmentValues = function(response){
setAttachments(response.data);
}
const fetchMedia = async ()=> {
setAttachments([]);
await apiCall().then((response) => {
setAttachmentValues(response);
});
}
useEffect(() => {
fetchMedia();
}, []);
return (
<>
<div className="w-full">
{(attachments.map((ele) => {
<div>{ele}</div>
)}
</>
)
}
apiCall() will return an array of objects.
setState in this way is working well in some cases. What is the actual issue here?
This way you can render data
import React, { useState, useEffect } from 'react';
export default ({ item }) => {
const [attachments, setAttachments] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((response) => {
setAttachments(response);
console.log(response);
});
}, []);
return (
<>
<div>
{attachments.map(item => <div key={item.username}> {item.username} </div> )}
</div>
</>
);
};

React useState infinity loop

I would like to learn React and therefore trying to build a logfile parser for myself to parse Apache HTTP Logs in CLF format.
However, trying to do this always causes an infinity loop.
import React, { useEffect} from "react";
import logfile from './logfile';
import parse from "clf-parser";
function App() {
const [logContent, setLog] = React.useState([]);
useEffect(()=>{
if(Object.keys(logContent).length === 0){
fetch(logfile)
.then(r => r.text())
.then(text => {
const data = text.split('\n').map(entry => {
return parse(entry);
});
return data;
}).then(
obj => {
console.log(obj);
setLog(obj);
return;
}
);
}
}, [])
return (
<div>
<header><h1>Logfile Parser</h1></header>
<main>{
logContent.map(entry => {
return (<div key={entry.key}>{entry.remote_addr}</div>)
}
)}</main>
</div>
);
}
It's directly related to the setLog(obj);, if I don't use it I have only two entries in my console. Why two and not one though? How to fix this problem?
As M. Elghamry pointed out correct in the comments, the checking for the logContent within the useEffect() was the problem.
After removing the if statement, the loop does not continue happening.
import React, { useEffect} from "react";
import logfile from './logfile';
import parse from "clf-parser";
function App() {
const [logContent, setLog] = React.useState([]);
useEffect(()=>{
fetch(logfile)
.then(r => r.text())
.then(text => {
const data = text.split('\n').map(entry => {
return parse(entry);
});
return data;
}).then(
obj => {
console.log(obj);
setLog(obj);
return;
}
);
}, [])
return (
<div>
<header><h1>Logfile Parser</h1></header>
<main>{
logContent.map(entry => {
return (<div key={entry.key}>{entry.remote_addr}</div>)
}
)}</main>
</div>
);
}

Why doesn't the axios response get saved in useState variable

I've built a random photo displaying feature in react.
the console says that the response is valid and it works,
but the page breaks when I return data.
Where is the issue?
Thanks in advance!
import React from 'react'
import { useEffect, useState } from 'react'
import axios from 'axios'
function RandomPhoto() {
const url = `https://api.unsplash.com/photos/random/?client_id=${process.env.REACT_APP_UNSPLASH_KEY}`
const [data, setData] = useState()
const getPhoto = () => {
axios.get(url)
.then(response => {
setData(response.data)
console.log(response.data) // <------- works
})
.catch(error => {
console.log(error)
})
}
useEffect(() => {
getPhoto()
},[])
console.log("XX" + data) // <---------- doesn't work, and following return() neither
return (
<div>
<img href={data.urls.regular} alt={data.alt_description}/>
<p>Photo by {data.username} {data.name} from {data.location} - found on unsplash</p>
</div>
)
}
export default RandomPhoto
I modified your code a bit, and it's working. I made it as an async function and changed the path of JSON object keys.
Please note the location data sometimes returns as null. So you have to render it conditionally.
import React from 'react';
import { useEffect, useState } from 'react';
import axios from 'axios';
const RandomPhoto = () => {
const url = `https://api.unsplash.com/photos/random/?client_id=${process.env.REACT_APP_UNSPLASH_KEY}`;
const [imageData, setImageData] = useState('');
const getPhoto = async () => {
await axios
.get(url)
.then((response) => {
setImageData(response.data);
})
.catch((error) => {
console.log(error);
});
};
useEffect(() => {
getPhoto();
}, []);
return (
<div>
<p>Hello</p>
<img src={imageData.urls?.regular} />
<p>
Photo by {imageData?.user?.username} {imageData?.user?.name} from{' '}
{imageData?.location?.country} - found on unsplash
</p>
</div>
);
};
export default RandomPhoto;

React js and Axios

I am trying to get this to display the price of Ethereum, but I cannot get it to display.
Can someone please help me? What should I change to get it to work?
Thanks!
import axios from "axios";
const Crypto = () =>{
const [post, setPost] = React.useState([]);
useEffect(() =>{
axios.get('https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=aud')
.then ((response) => {
setPost(response.data)
})
.catch(error => console.log('error'));
}, []);
return(
<div>
<h1> Test </h1>
<h1>{post.ethereum}</h1>
</div>
)
}
export default Crypto;
You need to import useEffect from React.
import React, { useEffect, useState } from "react";
import axios from "axios";
const App = () => {
const [post, setPost] = useState([]);
useEffect(() => {
axios
.get(
"https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=aud"
)
.then((response) => {
setPost(response.data);
})
.catch((error) => console.log("error"));
}, []);
return (
<div>
<h1> Test </h1>
<h1>{JSON.stringify(post.ethereum)}</h1>
</div>
);
};
export default App;

map array of objects from an api react

I have been trying to get the images from this API to append to the page by mapping through them, but I keep getting one of two error messages saying 'undefined.map is not a function' or 'getBirds.map is not a function.'I've tried leaving the array of objects as it is and setting state to an object and an array(at separate times) but that didn't work. I've also tried using Object.key, Object.values, and Object.entries(each at separate times) to turn the array of objects into an array and then map through my variable and through getBirds(again separately) but those attempts also failed. I have attached three of my attempts below. Can someone help me understand where I've gone wrong?
// Attempt 1
import {useState, useEffect} from 'react'
import axios from 'axios'
function Birds(props) {
const [getBirds, setGetBirds] = useState({})
const {image} = props
useEffect(() => {
async function fetchBirds() {
const URL = `https://audubon-society-api.herokuapp.com/birds`
try {
const res = await axios.get(URL)
console.log(res.data)
setGetBirds(res.data)
} catch (error) {
console.log(error)
}
}
fetchBirds()
}, [])
if (!getBirds) return <h3>Loading...</h3>
return (
<div>
<img src={getBirds.map(image)} alt={getBirds.map(image)}></img>
</div>
)
}
export default Birds
// Attempt 2
import {useState, useEffect} from 'react'
import axios from 'axios'
function Birds(props) {
const [getBirds, setGetBirds] = useState([])
const {image} = props
useEffect(() => {
async function fetchBirds() {
const URL = `https://audubon-society-api.herokuapp.com/birds`
try {
const res = await axios.get(URL)
console.log(res.data)
setGetBirds(res.data)
} catch (error) {
console.log(error)
}
}
fetchBirds()
}, [])
if (!getBirds) return <h3>Loading...</h3>
return (
<div>
<img src={getBirds.map(image)} alt={getBirds.map(image)}></img>
</div>
)
}
export default Birds
// Attempt 3
import {useState, useEffect} from 'react'
import axios from 'axios'
function Birds(props) {
const [getBirds, setGetBirds] = useState({})
const {image} = props
useEffect(() => {
async function fetchBirds() {
const URL = `https://audubon-society-api.herokuapp.com/birds`
try {
const res = await axios.get(URL)
console.log(res.data)
setGetBirds(res.data)
} catch (error) {
console.log(error)
}
}
fetchBirds()
}, [])
const birds = Object.entries(getBirds)
birds.forEach(([key, value]) => {
console.log(key, value)
})
if (!getBirds) return <h3>Loading...</h3>
return (
<div>
<img src={birds.map(image)} alt={birds.map(image)}></img>
</div>
)
}
export default Birds
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
You would need to initialize your state with an array, so the map function won't get errors, and correct the way you map it:
Initialize state with an array:
const [getBirds, setGetBirds] = useState([]);
Map it:
return (
<div>
{getBirds.map((bird) => (
<img src={bird.image} alt={bird.image}></img>
))}
</div>
);
Also, check your array with length, because [] or {} both equal to true.
if (!getBirds.length) return <h3>Loading...</h3>;
console.log(!![]);
console.log(!!{});
console.log(!![].length)
The completed solution:
import { useState, useEffect } from "react";
import axios from "axios";
function Birds(props) {
const [getBirds, setGetBirds] = useState([]);
useEffect(() => {
async function fetchBirds() {
const URL = 'https://audubon-society-api.herokuapp.com/birds';
try {
const res = await axios.get(URL);
console.log(res.data);
setGetBirds(res.data);
} catch (error) {
console.log(error);
}
}
fetchBirds();
}, []);
if (!getBirds.length) return <h3>Loading...</h3>;
return (
<div>
{getBirds.map((bird) => (
<img src={bird.image} alt={bird.image}></img>
))}
</div>
);
}
export default Birds;
Working Example:
Your init state of birds and setBirds should be an array [] not an object {}, also you don't need:
const birds = Object.entries(getBirds). fetch return array of birds already.
<img src={birds.map(image)} alt={birds.map(image)}></img> is wrong, the array loop map should render an image for each bird.
Below code will run for your need:
import React, {useState, useEffect} from "react";
import axios from 'axios';
function Birds(props) {
//- const [getBirds, setGetBirds] = useState([])
//- const {image} = props
// +
const [birds, setGetBirds] = useState([])
useEffect(() => {
async function fetchBirds() {
const URL = `https://audubon-society-api.herokuapp.com/birds`
try {
const res = await axios.get(URL)
console.log(res.data)
setGetBirds(res.data)
} catch (error) {
console.log(error)
}
}
fetchBirds()
}, [])
// - const birds = Object.entries(getBirds)
// - birds.forEach(([key, value]) => {
// - console.log(key, value)
// - })
// - if (!getBirds) return <h3>Loading...</h3>
if (!birds) return <h3>Loading...</h3>
return (
<div>
{/* <img src={birds.map(image)} alt={birds.map(image)}></img> */}
{birds.map((item, index) =>
<img src={item.image} alt={index}></img>
)}
</div>
)
}
export default Birds

Resources