in map function why I cannot reach all elements? - javascript

Hello everyone I have function like that.When I tried to call my datas I can just reach to first index of each array.For example I have 5 different pictures of playstation but on my web page I just see 1 picture. How can I fix it?Is something missing in function or should change to function ?
in advance thank you
import React from 'react'
import { gql, useQuery } from '#apollo/client';
import { Image } from 'antd';
import { useState } from 'react';
const GET_TECH = gql`
query AllItem{
categories{
name
products{
name
brand
attributes{
name
id
}
gallery
category
prices{
currency{
label
symbol
}
amount
}
inStock
description
}
}
}
`;
function Tech() {
const { loading, error, data } = useQuery(GET_TECH);
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
console.log(data);
return (
<div className='pageLayout'>
{
(data.categories).map((item,index) => {
//const {name,brand,description,gallery,category} = item;
{
return (item.products).map((itemPrdct,subIndex) => {
const {name,brand,description,gallery,category} = itemPrdct;
if(category === "tech"){
console.log(name)
return(
<div className="tech" key = {subIndex}>
<p className='nametag' >{brand}</p>
<Image width={200} src={gallery} className='gallery'/>
</div>
)
}
})
}
})
}
</div>
)
}
export default Tech
> //Graphql structure
{
"data": {
"categories": [
{
"name": "all",
"products": [
{
"name": "Nike Air Huarache Le",
"brand": "Nike x Stussy",
"attributes": [
{
"name": "Size",
"id": "Size"
}
],
"gallery": [
"https://cdn.shopify.com/s/files/1/0087/6193/3920/products/DD1381200_DEOA_2_720x.jpg?v=1612816087",
"https://cdn.shopify.com/s/files/1/0087/6193/3920/products/DD1381200_DEOA_1_720x.jpg?v=1612816087",
"https://cdn.shopify.com/s/files/1/0087/6193/3920/products/DD1381200_DEOA_3_720x.jpg?v=1612816087",
"https://cdn.shopify.com/s/files/1/0087/6193/3920/products/DD1381200_DEOA_5_720x.jpg?v=1612816087",
"https://cdn.shopify.com/s/files/1/0087/6193/3920/products/DD1381200_DEOA_4_720x.jpg?v=1612816087"
],
console.log

I was thinking if gallery is an array then it should use map on arrays
const {name,brand,description,gallery,category} = itemPrdct;
if(category === "tech"){
console.log(name)
return(
<div className="tech" key = {subIndex}> // key can be `${idx}${subIndex}` if products are repeating
<p className='nametag' >{brand}</p>
gallery?.map((url, idx) => {
return (<Image key={idx} width={200} src={url} className='gallery'/>)
}
</div>
)
} // else { return (<EmptyElement /> } // consider returning empty element
})
// map through the image
gallery?.map((url, idx) => {
return (<Image key={idx} width={200} src={url} className='gallery'/>)
}
you can use useMemo to transform the response and filter out empty elements then map the items as needed
hope it works

Related

How to make correct loop of JSON in React

I've got a problem with making a correct loop in React. I want to fetch data from JSON to don't repeat components. I tried to make two loops and then two maps, but everything was in bad order. The other problem is that "description" is also an array that's why I'm not able to deal with it
JSON:
{
"oswiecim": [
{
"header": "Oświęcim Zasole",
"description": [
"Rejon ulic św Maksymiliana Kolbego",
"i Stanisławy Leszczyńskiej"
]
},
{
"header": "Oświęcim Zasole",
"description": [
"Rejon ulic Więźniów Oświęcimia",
"Obozowej, Polnej i Legionów"
]
},
{
"header": "Stare Miasto",
"description": [
"Rejon Rynku i Placu ks. Jana Skarbka oraz ",
"ulic Zamkowej i Władysława Jagiełły"
]
},
{
"header": "Stare Miasto",
"description": [
"Cmentarz Parafialny oraz rejon",
"ul. Wysokie Brzegi."
]
},
{
"header": "Osiedle Chemików",
"description": [
"Największa pod względem liczby ludności",
"dzielnica Oświęcimia"
]
}
]
}
React:
import '../../styles/selection/Selection.scss'
import { useEffect, useState } from 'react';
const Selection = () => {
const [data, setData] = useState({})
const getData = async () => {
await fetch('https://jsoneditoronline.org/#left=cloud.b95a27020e1c45e9b3a7c95a74fc5d49', {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(data => {
setData(data)
})
}
useEffect(() => {
getData()
}, [])
const headers = []
const descriptions = []
for (const item of data.oswiecim) {
headers.push(item.header)
descriptions.push(item.description)
}
return (
<div className="selection">
{headers.map(item => (
<h1>{item}</h1>
))}
{descriptions.map(item => (
item.map(elem => (
<p>{elem}</p>
))
))}
</div>
);
}
export default Selection;
The result should look like this:
You don't need to separate header and description in two different variables.
So try something like this:-
return (
<div className="selection">
{data.oswiecim?.map((item) => (
<>
<h1>{item.header}</h1>
{item.description?.map((description) => (
<p>{description}</p>
))}
</>
))}
</div>
);
Live demo
Replace the setData(data); with following. It will just give the array you need to iterate,
setData(data.oswiecim);
Remove the following code,
const headers = []
const descriptions = []
for (const item of data.oswiecim) {
headers.push(item.header)
descriptions.push(item.description)
}
Replace return statement with following,
<div className="selection">
{data &&
data.map(item => (
<>
<div>{item.header}</div>
{item.description &&
item.description.map(descriptionItem => <p>{descriptionItem}</p>)}
</>
))}
</div>

JSON in Gatsby with GraphQL

I have one JSON file named Test.json with all data in it.
[ { "name" : "Margo",
"birthDate": "1990.03.15",
"timetable": [
{"time": "8.00",
"task": "toDoMargoElem1"},
{"time": "9.00",
"task": "toDoMargoElem2"}
},
{ "name" : "Arthur",
"birthDate": "1990.03.15",
"timetable": [
{"time": "8.00",
"task": "toDoArthurElem1"},
{"time": "9.00",
"task": "toDoArthurElem2"}
}
}
I'd like to use call data from component, so I tried to call GraphiQL. Code exporter gives me
const ComponentName = () => {
const data = useStaticQuery(graphql`
{
allTestJson {
edges {
node {
name
timetable {
time
task
}
}
}
}
}
`)
return <pre>{JSON.stringify(data, null, 4)}</pre>
}
In my component Mycomponent I did next
import React from 'react'
import {useStaticQuery, graphql} from 'gatsby'
export default function Sched() {
const data = useStaticQuery(graphql`
{
allTestJson {
edges {
node {
name
timetable {
time
task
}
}
}
}
}
`)
const results = data.allTestJson.edges.map (({node}) => {
const {name, time, task} = node;
return {
name,
time,
task
}
})
return (<div>
{results.map (({eventName, time, task})=>
<div key = {name}>
{name}
{time}
{task}
</div>
)}
</div>
)
}
But as a result i see just construction like
<div> {name} </div>
<div> {name} </div>
How can I see {time, task}?
Why map doesn't show all nodes of my objects?
Check the object desctructing
const results = data.allTestJson.edges.map (({node}) => {
const {name, time, task} = node; // check here
const {name, timetable:{time, task}} = node; // this is an example of nested object destructing
return {
name,
time,
task
}
})
time and task are inside timetable nested object so the resulting code should look like:
import React from 'react'
import {useStaticQuery, graphql} from 'gatsby'
export default function Sched() {
const data = useStaticQuery(graphql`
{
allTestJson {
edges {
node {
name
timetable {
time
task
}
}
}
}
}
`)
return data.allTestJson.edges.map (({node}) => {
const {name, timetable} = node;
return <div key = {name}>
{name}
{timetable.map(item=><div key={item.task}>{item.time},{item.task}</div>)}
</div>
})
}
birthday field is not being queried (I guess it's a typo) so add it in the correct position.

How to write 2 fetch method for contact API and Message API in reactjs?

I'm new to reactjs. I could map the data from json API. My objective is when we save a number in contactlist, it should show the name in message list also. I want to create 2 fetch data i.e., messageData, ContactData that should compare the Phone numbers of message API and COntact API. If Phone number is same in contact API and Message API then it should return name otherwise it should return only phone number.
Contact json data would be like
[
{
"id": 1,
"name": "ABC",
"phone": "+91 789654123",
"email": "abcyz#gmail.com"
},
{
"id": 2,
"name": "DEF",
"phone": "+91 123456987",
"email": "defvu#gmail.com"
}
]
Contact Component:
import React, { Component } from "react";
import { Grid, Header, Button, Icon } from "semantic-ui-react";
import { Link } from 'react-router-dom'
class ComponentList extends Component {
state = {
peopleData: []
};
componentDidMount() {
fetch('./people.json')
.then(response => response.json())
.then(data => this.setState({ peopleData: data }));
}
pnum(num) {
return num.replace(/^\D/g, "");
}
render() {
const {peopleData} = this.state;
return(
<div>
{ peopleData.map(people =>
<Grid>
<Grid.Row key={people.id}>
<Grid.Column>
<Header>{people.name}</Header>
<span>{people.phone}</span>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Button trigger={<Link to={`/displayChat/${this.pnum(people.phone)}`}>
<Icon name='comment alternate outline' color='teal' /></Link>}/>
</Grid.Row>
</Grid>
)}
</div>
);
}
}
export default ComponentList;
Message API:
[
{
"id": 1,
"phone": "+91 789654123",
"message": "Hello everyone",
"isrespond": true,
},
{
"id": 2,
"phone": "+91 123456987",
"message": "hi",
"isrespond": false,
}
]
DisplayChat component:
fetchChat() {
const { phone } = this.props.match.params ;
fetch(`api/conversation/${phone}`)
.then(response => response.json())
.then(data => this.setState({ messageList: data})
);
}
render(){
const {messageList} = this.state;
const { phone } = this.props.match.params ;
return(
<div>
<ViewHeader phone={this.props.match.params}/>
<Container className="viewMessage ">
{messageList.map(data =>
<Grid>
<Grid.Row key={data.id}>
<p>{data.message}</p>
</Grid.Column>
</Grid.Row>
</Grid>
)}
</Container>
<TypeHere phone={this.props.match.params}/>
</div>
);
}
}
Can anyone help me in this?
const URL1= "contactApi"
const URL2= "messageApi"
I have used promise.all along with fetch to resolve both the endpoints
Promise.all([
fetch(URL1),
fetch(URL2),
]).then(responses => responses
).then(responses => Promise.all(responses.map(r => r.json())))
.then(data=>writeLogic(data));
function writeLogic(data){
let nameOrPhone;
const contactApiData = data[0]
const messageApiData = data[1]
let isPresent
for(let m of messageApiData){
isPresent=false
for(let c of contactApiData){
if(m.phone === c.phone){
isPresent=true
nameOrPhone.push(c.name)
}
}
if(!isPresent){
nameOrPhone.push(m.phone)
}
}
//update your state here if you are using React
//this.setState({nameOrPhone})
console.log(nameOrPhone)
}
data will contain result of both the endpoint in an array.
you can use the data and write your logic on top of it.
Ref: https://javascript.info/promise-api

mapping through array of objects

I am trying to map through the following data and return "Balance" but it keeps telling me that "coding" its undefined.
here its the array
"entry": [
{
"resource": {
"id": "1980438",
"type": {
"coding": [
{
"system": "https://www.medeo-health.com/uploads/1/1/8/1/118121028/s491564155970805143-c3-i1-w640_orig.jpeg",
"code": "25062444",
"display": "Balance"
}
]
},
"manufactureDate": "2017-01-08",
"expirationDate": "2020-01-08",
"owner": {
"reference": "Organization/1980437"
}
},
"search": {
"mode": "match"
}
}, ...
this is what I am trying:
import React, { Component } from 'react';
import Device from './Device/Device';
import axios from 'axios';
class Devices extends Component {
state = {
devices: null
}
componentDidMount() {
axios.get('http://hapi.fhir.org/baseDstu3/Device?organization=1980437&_include=Device:organization&_sort=device-name')
.then(res => {
this.setState({ devices: res.data.entry });
})
.catch(error => {
console.log(error);
})
}
render() {
let devices = <p style={{ textAlign: "left", margin: "0" }}>This practitioner have no devices!</p>;
if (this.state.devices) {
devices = this.state.devices.map(device => {
return (
<Device
key={device.resource.id}
name={device.resource.type.coding[0].display}
/>
)
});
}
return (
<div>
{devices}
</div>
);
};
};
export default Devices;
the id returns well but for name it keeps getting "Cannot read property 'coding' of undefined"
what I am doing wrong?
Got the Issue. You are getting undefined because the last object you are receiving does not contain a type property in it. Please Check
Try Something Like this
{this.state.devices.map(device => {
if (device.resource.type) { //check type property exists first then render
console.log(device.resource.type.coding[0].display);
return (
<p key={device.resource.id}>
{device.resource.type.coding[0].display}
</p>
);
} else return null;
})}

Reactjs having problems printing out fetched data

super noob question. However, I've been stuck with this issue for long enough now. I've been searching and have found the similar issue but have not been able to resolve it. I was hoping someone could point me in the right direction as to what I am doing wrong.
I am fetching data from an API, and I am able to log out the array, however, when I try to print it out I am having no luck. In the beginning, I was passing it through a reducer but then realized that was not ideal. Right now I am trying to get it to work, then I'll refactor the code into a functional component.
fetchOrders = async () => {
await axios.get('http://localhost:4200/ordenes').then( res => {
this.setState({
prescription: res.data
})
})
}
render() {
console.log(this.state.prescription)
return (
<div >
<Paper style={styles.orderCard}id='orderCardContainer' >
<div id="profileCardContainer" style={styles.profileCard}>
<aside className='profileCardContainer'>
<ProfileCard />
</aside>
</div>
{this.renderOrder()}
</Paper>
</div>
)
}
}
The array I receive back from the API looks something like this:
Array(18)
0: {order: Array(3), _id: "5b2af38fb315eb5630a0bc78", physicianName: "Alejandro", patientName: "Alex", createdAt: "2018-06-21T00:38:39.376Z", …}
UPDATE:
class OrderCard extends Component {
constructor(props) {
super(props)
this.state = { prescription: []}
}
fetchOrders = async () => {
const res = await axios.get('http://localhost:4200/ordenes')
this.setState({
prescription: res.data
})
}
componentDidMount() {
this.fetchOrders()
}
renderOrder() {
if (this.state.prescription.length === 0 ) {
return (
<h1>Loading...</h1>
)
} else {
return (
this.state.prescription.map( (x, i) => {
<li>
{console.log(x.patientName)}
<h1>{ x.patientName }</h1>
</li>
})
)}
}
render() {
console.log(this.state.prescription)
return (
<div >
<Paper style={styles.orderCard}id='orderCardContainer' >
<div id="profileCardContainer" style={styles.profileCard}>
<aside className='profileCardContainer'>
<ProfileCard />
</aside>
</div>
<div id='orders' >
{ this.renderOrder() }
</div>
</Paper>
</div>
)
}
}
function mapStateToProps(state) {
return {
auth: state.auth.authenticated,
}
}
export default connect(mapStateToProps, actions)(OrderCard)
BACKEND SCHEMA
const orderObj = new Schema({
name: String,
price: Number,
}, { _id : false })
const orderSchema = new Schema (
{
physicianName: String,
patientName: String,
order: {type: [orderObj]}
},
{
timestamps: true
}
)
POSTMAN API RESULTS
[
{
"order": [
{
"name": "Asteraceae",
"price": 41.24
},
{
"name": "Liliaceae",
"price": 39.24
},
{
"name": "Fabaceae",
"price": 34.91
}
],
"_id": "5b2af38fb315eb5630a0bc78",
"physicianName": "Alejandro",
"patientName": "Alex",
"createdAt": "2018-06-21T00:38:39.376Z",
"updatedAt": "2018-06-21T00:38:39.376Z",
"__v": 0
}
]
Thanks in advance for tips.
Wrong brackets, you're not returning react element, try fixed one.
renderOrder() {
if (this.state.prescription.length === 0 ) {
return (
<h1>Loading...</h1>
)
} else {
return (
this.state.prescription.map((x, i) => (
<li>
{console.log(x.patientName)}
<h1>{ x.patientName }</h1>
</li>
))
)}
}
and fix this
fetchOrders = async () => {
const res = await axios.get('http://localhost:4200/ordenes');
this.setState({
prescription: res.data
});
}

Categories

Resources