Javascript saying object value is undefined. What am I doing wrong? - javascript

I'm trying to display the value of an object within an array of Github repositories (retrieved from a parsed JSON) in my React app but I'm getting an error that the browser can't read property key of undefined.
I'm able to console.log the JSON data and the objects within it but if I try to log the values within those objects, I get the error.
const App = () => {
const [repoList, setRepoList] = useState({});
useEffect(() => {
fetch("https://example.com/api")
.then(res => res.json())
.then(data => setRepoList(data));
});
return (
<div>{repoList[0].id}</div>
)
}
If I put JSON.stringify(repoList) within the div element, it shows the data.
If I put JSON.stringify(repoList[0]) within the div element, it also shows the data.
But if I put something like repoList[0].id nothing appears. This happens with each key listed. And I can confirm that the key is there. What am I doing wrong?

Try this.
const [repoList, setRepoList] = useState([]); // Change to array not object.
...
return repoList.length ?
(<React.Fragment>{repoList[0].id}</React.Fragment>)
: (<span>Loading ....</span>)
If your div does not have styles, better user Fragment, it result in better performance.

You're calling async functions to populate the repo list. The first time the return tries to use repoList[0].id, there is no repoList[0]. You may want to initialize repoList to a non-error-ing dummy object when you set it up with useState({})

Related

React Native 'ERROR TypeError: Cannot convert undefined value to object'

I'm trying to retrieve data in this way:
useEffect(() => {
async function fetchData() {
const response = await fetch('https://hasanadiguzel.com.tr/api/kurgetir');
const json = await response.json();
setData(json);
}
fetchData();
}, []);
console.log(data.TCMB_AnlikKurBilgileri[0].Isim);
When I run console.log(data.TCMB_AnlikKurBilgileri); upon opening the application, the API seems to be working fine and the data is being retrieved. However, when I try to retrieve data.TCMB_AnlikKurBilgileri[0].Isim with console.log(data.TCMB_AnlikKurBilgileri[0].Isim);, I get the error: ERROR TypeError: Cannot convert undefined value to object.
But, when I save the application after running console.log(data.TCMB_AnlikKurBilgileri); and then run console.log(data.TCMB_AnlikKurBilgileri[0].Isim);, it works without any problems and gives the output.
How can I solve this issue? note: You can watch the video to better understand my problem https://youtu.be/x_mlvMDzUt4
You are trying to console.log outside of useEffect. It cause the problem since your api did not fetch data yet, but you are trying to log data.
So, move your console.log inside of useEffect to check api response is correct.
const json = await response.json();
console.log(json.TCMB_AnlikKurBilgileri[0].Isim);
setData(json);
At first when you render the component, data has no any value(so maybe undefined) if you did not set initial value. Once api request done and updated state with response, your UI will updated with correct value.
You are trying to assign an object to an array. data is array and json is an object.
Instead of empty array use null as default value:
const [data, setData] = useState(null)
In order to track data changes you should also add a separate useEffect
useEffect(() => {
console.log(data?.TCMB_AnlikKurBilgileri[0]?.Isim)
},[data])

Having trouble displaying object property

I'm building a small pokedex using PokeAPI. I'm retrieving data from an endpoint and building my own object. The function that I've built for the latter runs on page load as follows:
$: pokemon = []
//fetch pokemon from PokeAPI
function getPokemon(){
let index = 0
fetch("https://pokeapi.co/api/v2/pokemon?limit=151") //
.then(response => response.json()) //
.then(allpokemon => {
allpokemon.results.map((poke) =>
pokemon = [...pokemon, {
index: index++,
name: poke.name
}]
)})
}
//populate pokemon array on page load
getPokemon()
I'm able to console log the object and traverse it in devtools, and also able to JSON stringify it and display within html. But whenever I try to retrieve a specific attribute, I receive a 500 error. For instance, I'm trying to display the current pokemons name in an h1 tag :
<h1>{pokemon[currentPokemon].name</h1> // this doesn't work
whereas
<h1>{pokemon[currentPokemon]</h1> //this does
This can't be too complicated of a fix, I just don't know what I'm missing, because I've been traversing objects for what I thought was the correct way for years now. Thank you.
This line is missing a curly brace at the end
<h1>{pokemon[currentPokemon].name</h1>
Besides that pokemon will initially be an empty array, so independent of currentPokemon the value will be undefined and accessing the key name will give the error Cannot read properties of undefined (reading 'name') which could be solved by adding a questionmark (Optional chaining)
<h1>{pokemon[currentPokemon]?.name}</h1>
There's no need for the $:, just let pokemon = []
.map() returns an array, so instead of setting pokemon inside the function better assign it the result. The index would be available as second parameter inside .map()
.then(allpokemon => {
pokemon = allpokemon.results.map((poke, index) => {
return {
name: poke.name, // or ...poke, to keep all fields
index
}
})
Writing the index in the data might not be neccessary if an #each loop is used to display the data
{#each pokemon as p, index}
<p>
{index} - {p.name}
</p>
{/each}
Try this:-
<h1>{pokemon[currentPokemon]['name']}</h1>

Cannot read property '0' of undefined when I change back tabs in React

I am working on a personal project and I am trying to fetch data from an API that I have running on my server. Before the first implementation of the code, everything works fine, even after I write my code and save it the first time it works alright. But after I do this and switch my navigation tabs back and forth once, everything breaks and I get "TypeError: Cannot read property '0' of undefined"
I would like to fetch all my data in one place and then just get what I need from it willingly.
This is the fetching function:
//i have my state here
const [rezultateEz, setRezultateEz] = useState()
//code for fetching the data
const ezFetcher = async () => {
const intrebare = await fetch('http://localhost:5000/ezquestions')
const res = await intrebare.json();
setRezultateEz(res)
}
//i then call my function inside a useEffect
useEffect(() => {
ezFetcher();
}, [])
//and so i can just test it i try to run it inside this JSX here
<div className={style.questionHolder}>
{rezultateEz[0].question}
</div>
The res property has a question, all_answers array and correct_answer inside it, which I want to access more easily with this function but I can't really do it because of the error presented earlier. How can I do that?
I tried using try catch or saving different pieces of state individually but nothing worked.
I will kindly accept any piece of advice or information given, and thank you for the time you spent reading my question
All I had to do was to set
const [rezultateEz, setRezultateEz] = useState([])

React Native w/ firebase "undefined is not an object"

Getting this error:
TypeError: undefined is not an object (evaluating 'doc.data().books')
from this code:
const getData = () => {
const snapshot = db.collection('users').doc(userEmail).onSnapshot((doc) => {
setData(doc.data().books)
})
}
useEffect(() => {
getData()
}, [])
this is the firestore database, trying to get to the updated boo collection (gets shown in a flatlist that needs to get updated when new content is added to the collection) Note that there's a users collection that is offscreen.
I'm pretty sure it's something that I'm doing wrong on my snapshot but I'm really not sure what, all help is greatly appreciated :)
The error is telling you that doc.data() returned undefined, which means the document you requested doesn't exist. You probably passed a value for userEmail other than what you expected it to be. Since you didn't show the value, we don't know for sure what went wrong.
I will point out that document IDs must be exact matches, so if the email address wasn't exactly "Email#email.com" with a capital E, the query will not return a document using what you've shown here.
There are several possibilities. However, db is not defined within the scope of the getData function... where is it defined?
If I correctly understand your question, you want to get the documents in the books (or boo?) subcollection of the user document with id corresponding to userEmail.
If this assumption is correct, you should do as follows:
const getData = () => {
db.collection('users').doc(userEmail).collection('books')
.onSnapshot(querySnapshot => {
var books = [];
querySnapshot.forEach(doc => {
books.push(doc.data());
});
// Here you have an array of all the book objects.
// It's up to you to use it as you wish with your setData() function
});
}
Note that with doc.data().books you are actually trying to get the books field of the user doc.

Adding variables to response data call in javascript

Is it possible to concatenate variable to a call to response data like so:
res.data.{some_variable}?
I am using axios to call an api, I get a JSON response and in order to get some specific info I have to call each key of the object. The keys are all numbered, "object_1", "object_2", "object_3" and so on. Right now I currently have to call it as many times as the keys are, but I'm wondering if there is a better way to do it.
I have tried res.data.object_${nr} but that didn't work.
This is my code:
const path= "path_to_api";
const object_nr = this.$route.params.nodeID;
axios.get(path)
.then((res) => {
this.object_devices = res.data.object_1;
})
.catch((error) => {
console.error(error);
});
But I would like to be able to add the object_nr like so: res.data.object_{object_nr}
You can get property using index syntax:
object['name']
So you can build your own index:
const foo = 'bar';
object[`name_${foo}`]

Categories

Resources