Can't bind JSON data with map function - javascript

I have this JSON below for example and I need to get the name of genres.
{
"adult": false,
"backdrop_path": "/5qxePyMYDisLe8rJiBYX8HKEyv2.jpg",
"budget": 178000000,
"genres": [
{
"id": 12,
"name": "Adventure"
},
{
"id": 28,
"name": "Action"
},
{
"id": 53,
"name": "Thriller"
}
],
"homepage": null
}
But when I use the map function the React return a error:
TypeError: this.state.persons.map is not a function
class Content extends React.Component {
state = {
persons: []
}
componentDidMount() {
axios.get(Config.apiUrl + 353081 + Config.apiKey)
.then(res => {
const persons = res.data;
this.setState({ persons });
})
}
render() {
return (
<div>
<Grid>
<Grid item xs={9}>
<Typography gutterBottom={true}><b>Budget:</b> { this.state.persons.budget }</Typography>
<Typography gutterBottom={true}><b>Genres:</b> { this.state.persons.map(person => <li key={person.genres.id}>{person.genres.name}</li>) }</Typography>
</Grid>
</Grid>
</div>
);
}
}

I think you state should be an object literal {}, not []. Also res.data returns an {..}, not []. If it returns an array, then this.state.persons.budget should throw error, but it doesn't. That proves, persons state is not an array.
state = {
persons: {
genres: []
}
}
And then
<Typography gutterBottom={true}>
<b>Genres:</b>{" "}
{this.state.persons.genres.map(genre => <li key={genre.id}>{genre.name}</li>)}
</Typography>;

Related

how do i fetch data by id on react native (rest api)

import React, { Component } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-
native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true
};
}
async getMovies() {
try {
const response = await
fetch('https://reactnative.dev/movies.json');
const json = await response.json();
this.setState({ data: json.movies });
} catch (error) {
console.log(error);
} finally {
this.setState({ isLoading: false });
}
}
componentDidMount() {
this.getMovies();
}
render() {
const { data, isLoading } = this.state;
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.title}, {item.releaseYear}</Text>
)}
/>
)}
</View>
);
}
};
this is the api
{
"title": "The Basics - Networking",
"description": "Your app fetched this from a remote endpoint!",
"movies": [
{ "id": "1", "title": "Star Wars", "releaseYear": "1977" },
{ "id": "2", "title": "Back to the Future", "releaseYear": "1985" },
{ "id": "3", "title": "The Matrix", "releaseYear": "1999" },
{ "id": "4", "title": "Inception", "releaseYear": "2010" },
{ "id": "5", "title": "Interstellar", "releaseYear": "2014" }
]
}
I want this code to fetch and show data by id. just like the query show movies by id.
This is the result.
I try to fetch data with id 1 but i dont know how to do it. i dont know how to show it to react native. and i dont know how fetch the data by id
I pass a parameter like this:
my call to the API:
const getDetails = (id) => {
return api.Get(`/api/details/${id}`);
}
then in the react code
const getInfo = async(e) => {
apiCall.GetDetails(value to be passed here)
}

Although sometimes it works, I get ".filter is not a function" in my React project

28 | <Grid.Row>
29 | {cars.map((car) => (
30 | <Grid.Column style={{marginBottom:"1em"}}>
> 31 | <CarComponent car={car} imagePath={carImages.filter(image=>image.car.id===car.id)[0].imagePath}></CarComponent>
| ^ 32 |
33 | </Grid.Column>
34 | ))}
I get the information (brand, color, description etc.) and photos of the vehicles from separate services (carController, carImageController). As such, when trying to list the cars, I choose the photo with the carId equal to the id of that car in the list of photos for each car in the car list. I write the imagePath as carImages.filter(image=>image.car.id===car.id)[0].imagePath} to do this check on the data coming from my photo service and send it as props to the car component. Sometimes I get this typeError when everything is working fine. Why might it be caused?
Car Function Component:
export default function CarComponent({ car, imagePath}) {
return (
<div>
<Card style={{height:"388px"}}>
<Image
src={imagePath}
wrapped
ui="false"
style={{height:"200px"}}
/>
<Card.Content>
<Card.Header>{car.brand.name}</Card.Header>
<Card.Meta>
<span className="date">{car.modelYear}</span>
</Card.Meta>
<Card.Description>{car.description}</Card.Description>
</Card.Content>
<Card.Content extra style={{color:"black"}} >
<h3 >{car.dailyPrice} ₺</h3>
<Button secondary animated>
<Button.Content visible>Kirala</Button.Content>
<Button.Content hidden>
<Icon name="arrow right" />
</Button.Content>
</Button>
</Card.Content>
</Card>
</div>
);}
Car Image Class
export default class CarImageService{
getCarImages(){
return axios.get("http://localhost:8080/api/images/getAll")
}
}
CarsList Page
export default function CarsList() {
const [cars, setCars] = useState([]);
const [carImages, setCarImage] = useState({});
useEffect(() => {
let carImageService = new CarImageService();
carImageService
.getCarImages()
.then((result) => setCarImage(result.data.data));
}, []);
useEffect(() => {
let carService = new CarService();
carService.getCars().then((result) => setCars(result.data.data));
}, []);
return (
<div>
<Grid columns={3} >
<Grid.Row>
{cars.map((car) => (
<Grid.Column style={{marginBottom:"1em"}}>
<CarComponent car={car} imagePath={carImages.filter(image=>image.car.id===car.id)[0].imagePath}></CarComponent>
</Grid.Column>
))}
</Grid.Row>
</Grid>
</div>
);
}
Get All Car Images Request URL: http://localhost:8080/api/images/getAll
Get All Car Images Response Body:
{
"success": true,
"message": null,
"data": [
{
"id": 26,
"imagePath": "http://res.cloudinary.com/dp39jsge0/image/upload/v1629406293/hx80jyfrus88tar0psq4.png",
"createdAt": "2021-08-19",
"car": {
"id": 1,
"modelYear": 2017,
"dailyPrice": 600,
"description": "A6 2.0TDI QUATTRO EDITION",
"brand": {
"id": 2,
"name": "Audi"
},
"color": {
"id": 8,
"name": "Beyaz"
},
"busy": false
}
},
{
"id": 27,
"imagePath": "http://res.cloudinary.com/dp39jsge0/image/upload/v1629406541/dynoc7dnjcbns0mv2y1m.png",
"createdAt": "2021-08-19",
"car": {
"id": 2,
"modelYear": 2018,
"dailyPrice": 400,
"description": "ALFA ROMEO GIULIETTA 1.6 JTD PROGRESSİON 120 HP",
"brand": {
"id": 1,
"name": "Alfa Romeo"
},
"color": {
"id": 9,
"name": "Gri"
},
"busy": false
}
},
{
"id": 28,
"imagePath": "http://res.cloudinary.com/dp39jsge0/image/upload/v1629406744/fmvdbmqaennil4ptdyoc.png",
"createdAt": "2021-08-19",
"car": {
"id": 3,
"modelYear": 2018,
"dailyPrice": 550,
"description": "BMW 320 DİZEL OTOMATİK-EDITION M SPORT",
"brand": {
"id": 3,
"name": "BMW"
},
"color": {
"id": 10,
"name": "Kırmızı"
},
"busy": false
}
},
{
"id": 29,
"imagePath": "http://res.cloudinary.com/dp39jsge0/image/upload/v1629406930/dq4htj3rrdjlbpiqa8iq.png",
"createdAt": "2021-08-20",
"car": {
"id": 4,
"modelYear": 2016,
"dailyPrice": 700,
"description": "C180 COUPE",
"brand": {
"id": 10,
"name": "Mercedes - Benz"
},
"color": {
"id": 11,
"name": "Lacivert"
},
"busy": false
}
}
]
}
Refresh page a few times:sample of list of cars
The initial value for carImages must be array, not object.
const [carImages, setCarImage] = useState([]);
Notice the initial value: [], not {}
For the second error:
You need to check the result of filter because filter returns an empty array when getCars() returns before getCarImages() or if some cars don't have any images. Plus, to get rid of the array, you need to use find instead of filter because you expect a single result.
export default function CarsList() {
const [cars, setCars] = useState([]);
const [carImages, setCarImage] = useState([]);
useEffect(() => {
let carImageService = new CarImageService();
carImageService
.getCarImages()
.then((result) => setCarImage(result.data.data));
}, []);
useEffect(() => {
let carService = new CarService();
carService.getCars().then((result) => setCars(result.data.data));
}, []);
return (
<div>
<Grid columns={3} >
<Grid.Row>
{cars.map((car) => {
let image = carImages.find(i=>i.car.id===car.id);
return
<Grid.Column style={{marginBottom:"1em"}}>
<CarComponent car={car} imagePath={image === undefined ? undefined :image.imagePath}></CarComponent>
</Grid.Column>
})}
</Grid.Row>
</Grid>
</div>
);
}

TypeError: .json WEBPACK_IMPORTED_MODULE_2__.filter is not a function

I am getting error when i try to get data from json file at this line in my code selectedEmployee: employeeList.data.Table[0],
TypeError: _employeeList_json__WEBPACK_IMPORTED_MODULE_2__.filter is
not a function
//App.js
const filterEmployee = (searchText, maxResults) => {
return employeeList.filter((employee) => {
if (employee.data.Table.name.toLowerCase().includes(searchText.toLowerCase())) {
return true;
}
return false;
}).slice(0, maxResults);
}
var maxResults = 4;
export default class App extends React.Component {
constructor(){
super();
this.state = {
selectedEmployee: employeeList.data.Table[0],
filteredEmployee: filterEmployee('', maxResults)
}
}
onSearch = (event) => {
this.setState({
filteredEmployee: filterEmployee(event.target.value, maxResults)
});
}
onEmployeeClick = (employee) => {
this.setState({
selectedEmployee: {name: employee.name, info: employee.info, contact: employee.contact}
});
}
render() {
return (
<Col lg={8} md={7} sm={4} lgOffset={2}>
<Col lg={6}>
<HomePage onSearch={this.onSearch} employeeData={this.state.filteredEmployee} onEmployeeClick={this.onEmployeeClick}/>
</Col>
<Col lg={6}>
<EmployeePage selectedEmployee={this.state.selectedEmployee}/>
</Col>
</Col>
);
}
}
//my json file looks like this
{
"data": {
"Table": [
{
"id": "1001",
"name": "Alez",
"info": "Alez"
},
{
"id": "1002",
"name": "Baro",
"info": "Alez"
}
]
}
}
What i want to accomplish is using a different .json format.
these was the orginal json file format
[
{
"key": "t1",
"data":{
"name": "James",
"info": "Software Development",
"contact": {
"office": "781-000-002",
"mobile": "087-321-0292",
"sms": "617-000-002",
"email": "jtaylor#company.ie"
}
}
}
]
I want to use these json file format instead and update my code
{
"data": {
"Table": [
{
"id": "1001",
"name": "Alez",
"info": "Alez"
},
{
"id": "1002",
"name": "Baro",
"info": "Alez"
}
]
}
}
The error is related to the filter function call at the top of your code. You can only filter on an array. Therefore you need to call filter like using employeeList.data.Table as your array:
const filterEmployee = (searchText, maxResults) => {
return employeeList.data.Table.filter((employee) => {
// returns true if condition is met, otherwise returns false
return employee.name.toLowerCase().includes(searchText.toLowerCase());
}).slice(0, maxResults);
}
and then when checking if the employee.name includes the searchText, you can just access employee.name instead.

Fetch data from server (REST API) and set data in a Multiple Select Picker in React Native

I am using REST API to fetch the data from server and I want to set that data in a multiple select picker in React Native but I am getting an error. Here is my response from the server:
[
{
"id": 22,
"name": "Business",
"slug": "business"
},
{
"id": 17,
"name": "Digital Marketing",
"slug": "digital-marketing"
},
{
"id": 23,
"name": "Fun & Lifestyle",
"slug": "fun-lifestyle"
},
{
"id": 16,
"name": "Mobiles",
"slug": "mobiles"
}]
I want to set the name in the drop down and select multiple value from it. Here is my code:
import React from 'react';
import { View, StyleSheet } from 'react-native';
import MultiSelect from 'react-native-multiple-select';
export default class PostJob extends React.Component {
state = {
LangPickerValueHolder: [],
LangKnown: []
}
componentDidMount () {
fetch('taxonomies/get_taxonomy?taxonomy=project_cat').then(response => response.json())
.then(responseJson => {
let langString = responseJson;
let LangPickerValueHolder = langString.map((name, id) => { return { name, id }; });
this.setState({
LangPickerValueHolder
});
console.log(langArray);
}).catch(error => {
console.error(error);
});
}
render () {
return (
<View style={styles.container}>
<MultiSelect
ref={(component) => { this.multiSelect = component; }}
onSelectedItemsChange={(value) =>
this.setState({ LangKnown: value })
}
uniqueKey="id"
items={this.state.langString}
selectedItems={this.state.LangKnown}
onChangeInput={ (text) => console.log(text)}
displayKey = 'name'
submitButtonText="Submit" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'white',
padding: 8
}
});
But it is showing no item to display.
Your mapping is wrong. It should be langString.map(item => ({ name: item.name, id: item.id })).
items prop should be this.state.LangPickerValueHolder.

How to property call component inside same component using ReactJS?

I'm building a sidebar menu with submenu levels, and I'm using this code to build the menu and the submenus:
Sidebar menu:
import React from 'react';
import SidebarMenuItem from './SidebarMenuItem';
var menuData = require("./data/menu.json");
class SidebarMenu extends React.Component {
constructor(props)
{
super(props);
this.state = { expanded: true };
};
render() {
return (
<div>
{
menuData.map((item, index) => <SidebarMenuItem id={ index.toString()} key={index.toString()} {...item} />)
}
</div>
);
};
}
export default SidebarMenu;
SidebarMenuItem:
import React from 'react';
class SidebarMenuItem extends React.Component {
render() {
console.log(this.props.id);
return (
<div>
<a href={this.props.link}>{this.props.title}<i className={'fa ' + this.props.icon}/></a>
{this.props.submenu ? this.props.submenu.map((subitem, index) => <SidebarMenuItem key={this.props.id + index.toString()} {...subitem} />) : null }
</div>
)
}
}
SidebarMenuItem.propTypes = {
id: React.PropTypes.string,
key: React.PropTypes.string,
title: React.PropTypes.string,
ref: React.PropTypes.string,
icon: React.PropTypes.string,
submenu: React.PropTypes.array
}
export default SidebarMenuItem;
Although I can see the submenus on screen, I'm getting the following error:
Warning: SidebarMenuItem: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop.
Another clue that something is wrong is the console output:
0
1
undefined <-- I was supposed to get 11 and 12 here, as this option has 2 submenus
2
And finally my menu.JSON data:
[
{
"title": "Option1",
"link": "www.google.com",
"icon": "fa-edit"
},
{
"title": "Option2",
"link": "",
"icon": "fa-hello",
"submenu":
[
{
"title": "SubOption2.1",
"link": "wwww.yahoo.com",
"icon": "fa-asterisk"
},
{
"title": "SubOption2.2",
"link": "wwww.tisafe.com",
"icon": "fa-save"
}
]
},
{
"title": "Option3",
"link": "www.mezasoft.com",
"icon": "fa-save"
}
]
Help appreaciated to find out what's wrong with my code.
You are getting the warning because key is a restricted attribute and cannot be passed as a prop, change it to keyValue. Also you get undefined when you use this.props.id because in your SidebarMenuItem render function for submenus you are still calling the same component and there you are not passing the id as a prop. you can see that in the snippet below. I hope it helps
class SidebarMenu extends React.Component {
constructor(props)
{
super(props);
this.state = { expanded: true };
};
render() {
var menuData = [
{
"title": "Option1",
"link": "www.google.com",
"icon": "fa-edit"
},
{
"title": "Option2",
"link": "",
"icon": "fa-hello",
"submenu":
[
{
"title": "SubOption2.1",
"link": "wwww.yahoo.com",
"icon": "fa-asterisk"
},
{
"title": "SubOption2.2",
"link": "wwww.tisafe.com",
"icon": "fa-save"
}
]
},
{
"title": "Option3",
"link": "www.mezasoft.com",
"icon": "fa-save"
}
];
return (
<div>
{
menuData.map((item, index) => <SidebarMenuItem id={ index.toString()} keyValue={index.toString()} {...item} />)
}
</div>
);
};
}
class SidebarMenuItem extends React.Component {
render() {
console.log('in render',this.props);
return (
<div>
<a href={this.props.link}>{this.props.title}<i className={'fa ' + this.props.icon}/></a>
{this.props.submenu ? this.props.submenu.map((subitem, index) => <SidebarMenuItem keyValue={this.props.id + index.toString()} {...subitem} />) : null }
</div>
)
}
}
SidebarMenuItem.propTypes = {
id: React.PropTypes.string,
keyValue: React.PropTypes.string,
title: React.PropTypes.string,
ref: React.PropTypes.string,
icon: React.PropTypes.string,
submenu: React.PropTypes.array
}
ReactDOM.render(<SidebarMenu/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app"></div>

Categories

Resources