Hi I am trying to map an array of an api to display paragraphs for every index within the array. However I keep getting an error :
**> TypeError: undefined is not an object (evaluating
'post.game_indices.version.name')**
But when I console log post and use my buttons below it displays what I want and not undefined. So why is it undefined when I want to map the paragraphs?
'''
import React, {useEffect,useState} from 'react'
import instance from './axios'
const Home = () => {
const [post, setPost] = useState(null);
const [error,setError] = useState(null);
const [showTypes,setShowTypes]=useState(false);
const [showAbilities,setShowAbilities]=useState(false);
useEffect(() => {
instance.get("bulbasaur/").then((response) => {
setPost(response.data);
}).catch(error => {
setError(error);
})
},[]);
console.log(post);
if (error) return `Error: ${error.message}`;
if (!post) return 'no post!'
return (
<>
<h1>{post.name}</h1>
<button onClick={()=>setShowTypes(!showTypes)}>types</button>
{showTypes? <p>{(post.types[0].type.name)}</p>:null}
{showTypes? <p>{(post.types[1].type.name)}</p>:null}
<button onClick={()=>setShowAbilities(!showAbilities)}>abilities</button>
{showAbilities? <p>{(post.abilities[0].ability.name)}</p>:null}
{showAbilities? <p>{(post.abilities[1].ability.name)}</p>:null}
{/* <button onClick={gameVersion}>game versions</button> */}
{post.game_indices.version.name.map(name => <p key={post.game_indices.version.name}>{name}</p>)}
</>
)
}
export default Home;
'''
ok, I recreated your app and found a problem - you should map on array post.game_indices and then display index.version.name
{post.game_indices.map((index, idx) => <p key={idx}>{index.version.name}</p>)}
The error comes from the fact that you version is not an object in game_indices (it is undefined, which means maybe game_indices is an empty object or it does not contain the version key). Can you please check your post object again ?
Related
I am getting an error on my .map function. I believe the issue is greater than that though because sometimes my fetch comes back as undefined. I have been looking into solutions but haven't found anything that has given me a solution.
Props - is a logged-in user object that has the users ID
discBag consoles as an array sometimes but also will console as undefined. This is where I believe my issue is happening. I have looked into component mounting, but I was confused with the class and super() syntax.
here is the error I am getting along with the two console.logs
I am new to web development and this is my very first stack overflow question. Any solutions or guidance to the solution is greatly appreciated!
function DiscBag(props) {
const [loading, setLoading] = useState(true);
const [discBag, setDiscBag] = useState([]);
const userID = props.user.user.id;
console.log(userID)
console.log(discBag)
const getDiscs = async () => {
try {
const response = await fetch(`/users/${userID}`)
const data = await response.json()
setLoading(false)
setDiscBag(data.discBag)
} catch (error) {
console.log(error)
}
};
useEffect(() => {
getDiscs();
}, []);
if (loading) {
return <div> ....loading bro</div>;
}
return (
<div className="child">
<p>not loading</p>
{discBag.map((index, discs) => (
<div className="discs" key={index}>
{discs}
</div>
))}
</div>
);
}
According to your description, it seems that there are times that the call to your server does not return a data.discBag value, which causes the discBag state to be empty (and the map function can only run on arrays, here is the fix for the problem:
{discBag?.map((discs, index) => (
Can you try with {discBag.map((discs, index) => ... ? first one is element, second one is the index like below;
array.map((currentElement, index) => { something... })
Hi I am trying to get todo array field from cloud firestore database in a react project. When i print out with console log I can see the empty array symbol but It throws error at the same time and does not render the page.
This is the Firestore.js file to get data from firebase.
export const userTodoList = async (email) => {
await onSnapshot(doc(db, "users", email), (doc) => {
console.log(doc.data().todos);
return doc.data().todos;
});
};
This the MainPage.js file to get the array and pass to CardList component.
const MainPage = () => {
const todoArray = userTodoList(auth.currentUser.email);
const [todos, setTodos] = useState(todoArray);
return (
<div>
<section>
<NavBar></NavBar>
<ToDoForm />
</section>
<section>
<CardList array={todos} />
</section>
</div>
);
};
This is the CardList component to render the cards with the array mapping. I am checking for if the array length is 0 or not but still get errors.
const CardList = (props) => {
const array = props.array;
if (array.length === 0) {
return (
<div className="grid_container">
<h2>Found no todos</h2>
</div>
);
}
return (
<div className="grid_container">
{array.map((todo) => (
<Card title={todo.title} />
))}
</div>
);
};
Errors.
The object.map is not a function error occurs because the map method is not implemented on objects. To iterate over an object, use the Object.keys() method to get an array of the object's keys and call the map()method on the array of keys.
I.e You can use Object.keys() or Object.entries() and then use map
For example:
array.keys(obj).map(key => {
//other statements
});
For more details you can check this article
Can you help me figure out why I am not able to map this array. Here below are the error and the codes I am running:
TypeError: posts.map is not a function
and here is my codes causing the above error:
import React from 'react';
import {useEffect, useState} from 'react';
import { Container, Row, Col } from 'bootstrap-4-react';
export default function Post() {
//posts array to be mapped
const [posts, setPosts] = useState([{
title: "",
postContent: ""
}]);
useEffect(() => {
//fetches a GET route
fetch(`${process.env.REACT_APP_SERVER_URL}/posts/:id`).then(res => {
if (res.ok) {
return res.json()
}
}).then(jsonRes => setPosts(jsonRes));
})
return (
<div>
<h1>Hello</h1>
//cant seem to be able to map this array
{posts.map(post => {
<>
<h1>{post.title}</h1>
<p>{post.postContent}</p>
</>
})}
</div>
)}
You need to wrap the mapped returned code block within parenthesis ()
and not in curly brackets {} in order to return the html correctly
//...
return (
<div>
<h1>Hello</h1>
{posts.map(post => (
<>
<h1>{post.title}</h1>
<p>{post.postContent}</p>
</>
))}
</div>
)
}
Edit:
Also, I suggest adding an empty dependency array as the second argument for your useEffect(() => { //your code }, [])
This will make it so your component doesn't re-render sporadically and end up fetching your data a ridiculous amount of times.
This is maybe because the response is not an array. Try to console.log the response. You can also change its type by using Array.isArray(jsonRes). The second problem is you are not returning the individual element inside the map function.
{posts.map((post) => (
<>
<h1>{post.title}</h1>
<p>{post.postContent}</p>
</>
))}
Your useEffect also don't have any dependencies, this will result in fetching data on every render. So you must use an empty array as the second argument inside useEffect to tell it to execute only once.
useEffect(() => {
//fetches a GET route
fetch(`${process.env.REACT_APP_SERVER_URL}/posts/:id`).then(res => {
if (res.ok) {
return res.json()
}
}).then(jsonRes => setPosts(jsonRes));
}, [])
Im new in ReactNative and I'm trying to take some data from here https://www.dystans.org/route.json?stops=Hamburg|Berlin
When I try console.log results it return full API response. I dont know why in first results.distance works and return distance, but when I'm trying to do it inside FlatList nothing is returned. Sometimes it works when i want to return only item.distance but can't somethnig like <Text>{item.stops[0].nearByCities[0].city}</Text> nowhere in my code also in console. Im getting error:
undefined is not an object (evaluating 'results.stops[0]')
imports...
const NewOrContinueScreen = ({ navigation }) => {
const [searchApi, results, errorMessage] = useDystans();
console.log(results.distance);
return (
<SafeAreaView forceInset={{ top: "always" }}>
<Text h3 style={styles.text}>
Distance: {results.distance}
</Text>
<Spacer />
<FlatList
extraData={true}
data={results}
renderItem={({ item }) => (
<Text>{item.distance}</Text>
// <Text>{item.stops[0].nearByCities[0].city}</Text>
)}
keyExtractor={item => item.distance}
/>
<Spacer />
</SafeAreaView>
);
};
const styles = StyleSheet.create({});
export default NewOrContinueScreen;
And here is my hook code:
import { useEffect, useState } from "react";
import dystans from "../api/dystans";
export default () => {
const [results, setResults] = useState([]);
const [errorMessage, setErrorMessage] = useState("");
const searchApi = async () => {
try {
const response = await dystans.get("route.json?stops=Hamburg|Berlin", {});
setResults(response.data);
} catch (err) {
setErrorMessage("Something went wrong with useDystans");
}
};
useEffect(() => {
searchApi();
}, []);
return [searchApi, results, errorMessage];
};
As the name implies, FlatList is designed to render a list. Your API endpoint returns a JSON Object, not an Array, so there's nothing for the FlatList to iterate. If you want to show all the stops in the list, try passing in the stops list directly.
<FlatList
data={results.stops}
renderItem={({ item }) => (<Text>{item.nearByCities[0].city}</Text>)}
/>
Some side notes: (1) The extraData parameter is used to indicate if the list should re-render when a variable other than data changes. I don't think you need it here at all, but even if you did, passing in true wouldn't have any effect, you need to pass it the name(s) of the variable(s). (2) The keyExtractor parameter is used to key the rendered items from a field inside of them. The stop objects from the API don't have a member called distance so what you had there won't work. From my quick look at the API response, I didn't see any unique IDs for the stops, so you're probably better off letting React key them from the index automatically.
I'm attempting to map over data I received from an API call. Getting shallow endpoints works fine, but anything nested gives me an error.
The goal is to get all of the opening themes and display them in a 'ul'.
The exact error "TypeError: anime.opening_themes is undefined"
Repo to the project
Heres the endpoints.
Heres my component.
const AnimeDetails = (props) => {
const API = 'https://api.jikan.moe/v3/anime'
const initialState = {
anime: []
}
const [anime, setAnime] = useState(initialState)
useEffect(() => {
const getAnime = async () => {
const response = await fetch(`${API}/${props.match.params.animeId}`)
const data = await response.json()
console.log(data);
setAnime(data) // set initial state to hold data from our API call
}
getAnime()
}, []) // [] prevents useEffect from running in an infinite loop
return (
<AnimeDetailsWrapper>
<Title>{anime.title}</Title>
<Details>
{anime.opening_themes
.map((song, index) => (
<li key={index}>{song}</li>
))}
</Details>
</AnimeDetailsWrapper>
)
}
Your initial state is an empty array, not an empty object:
const initialState = {
anime: []
}
When your component mounts, there is no data yet, so you're attempting to render [].opening_themes.map, and obviously there is no opening_themes property on an empty array.
Set your initial state to an empty object instead:
const initialState = {}
And you will probably want to test that you have data before attempting to render it:
return anime.mal_id && (
<AnimeDetailsWrapper>
<Title>{anime.title}</Title>
<Details>
{anime.opening_themes
.map((song, index) => (
<li key={index}>{song}</li>
))}
</Details>
</AnimeDetailsWrapper>
)
This will prevent your component from rendering anything until your anime state contains a mal_id property.
The first time you render your component, the state anime is equal to {anime: []}, which has no property called opening_themes.
you should try like this
first, remove initialState code and use direct code like following
if the response is in the form of an array
const [anime, setAnime] = useState([])
if the response is in the form of an object
const [anime, setAnime] = useState({})
otherwise, null will work with any response
const [anime, setAnime] = useState(null)
return code like this
return (
<> {anime && <AnimeDetailsWrapper>
<Title>{anime.title}</Title>
<Details>
{anime.opening_themes
.map((song, index) => (
<li key={index}>{song}</li>
))}
</Details>
</AnimeDetailsWrapper>}</>
)