Access nested data api objects in react native - json

I need to access the data inside the object "priceRange" inside this api data structure 'https://api.chvcfcz6km-enapsysbu1-s1-public.model-t.cc.commerce.ondemand.com/geawebservice/v2/marketplace/products/search' but I haven't found the way to do it, I'm doing an axios call in react native as I show below:
export const RecommendationsView: React.FC = () => {
const [fetching, setFetching] = React.useState(true)
const navigation = useNavigation<NavigationProps>()
const [loading, setLoading] = useState(false)
const [items, setItems] = useState<any[]>([])
const getData = async () => {
const res = await axios.get(
'https://api.chvcfcz6km-enapsysbu1-s1-public.model-t.cc.commerce.ondemand.com/geawebservice/v2/marketplace/products/search'
)
console.log(res.data)
setItems(res.data.products)
setLoading(true)
setFetching(false)
//este setloading me habia funcionado la idea es reemplazarlo por el setfetching
}
React.useEffect(() => {
getData()
}, [])
return (
<View>
<View sx={Styles.header} />
{items?.map((item, index) => {
return (
<View key={index}>
<Text>{`${item?.name} + ${item?.priceRange}`}</Text>
</View>
)
})}
</View>
)
}
the call {item?.name} returns me correctly the items name, but if I do something like {item?.priceRange} or any of the data inside priceRange, it only returns [object Object] or undefined.

Your API return XML Response not JSON Response, you have to convert it to a json to make it work correctly.

Related

How to print json api data in reactjs

I'm fetching json api details through GET request and trying to print it. Getting an error:
Error in the console is Uncaught ReferenceError: allUsers is not defined
const Dashboard = ({status, juser}) => {
const [allUsers, setAllUsers] = React.useState([]);
const id = juser.actable_id;
console.log(id); //getting id here as 1
const getAllusers = () => {
axios
.get(`http://localhost:3001/user/${id}`, { withCredentials: true })
.then((response) => {
console.log(response.data);
setAllUsers(response.data);
})
.catch((error) => {
console.log(" error", error);
});
};
React.useEffect(() => {
getAllusers();
}, []);
{allUsers.map((job_seeker, index) => {
return (
<div>
<p>{job_seeker.name}</p>
</div>
);
})}
}
export default Dashboard;
I'm new to react. Any help is appreciatable.
const [state, setState] = React.useState([]);
the state is where your data is located and setState is function to reset the state from anywhere,
so on your code,
const [jobseekers, allUsers] = React.useState([]); // change string to array
jobseekers is the variable where your data is located and allUsers is the function to store data into state.
set data to state using allUsers function,
const getAllusers = () => {
axios
.get(`http://localhost:3001/user/${id}`, { withCredentials: true })
.then((response) => {
allUsers(response.data);
})
.catch((error) => {
console.log(" error", error);
});
};
and map from jobseekers
{jobseekers.map((job_seeker, index) => {
return (
<div>
<p>{job_seeker.name}</p>
</div>
);
})}
Also I would suggest to rename your state and setState as,
const [allUsers, setAllUsers] = React.useState([]);
You didn't pass the value of response to allUsers, instead, you just created a new variable. So change
const allUsers = response.data;
to:
allUsers(response.data)
Besides, you can also improve the way that you have used useState. You have initialized it as an empty string while you'll probably store an array from response in jobseekers. So, initialize it as an empty array.
const [jobseekers, allUsers] = React.useState([]);

How to loop through a JSON array with useEffect in React?

I am trying to loop through a JSON array with useEffect. When I use the below code (with the array removed from useState) with a single user specified, I am able to get the data. However it does not work with the entire array...any suggestions would be appreciated.
function GitHubUser() {
const [data, setData] = useState([]);
useEffect(() => {
fetch(`https://api.github.com/users/`)
.then(res => res.json())
.then(setData)
.catch(console.error);
}, []);
if (data) {
return (
<div>
<h1>{data.userId}</h1>
<img src={data.avatar_url} width={100} alt={"github avatar"}/>
<p>{data.login}</p>
</div>
);
}
return null;
}
It doen't work because when you do if (data) it returns true because empty array is true
const data = [];
if (data) {
console.log("Empty array is true");
} else {
console.log("Empty array is false");
}
So... when you try to get userId from an empty array it throws an error.
If data is supposed to be an array...
function GitHubUser() {
const [data, setData] = useState([]);
useEffect(() => {
fetch("https://api.github.com/users")
.then((res) => res.json())
.then(setData)
.catch(console.error);
}, []);
if (data) {
return (
<React.Fragment>
{data.map((user) => (
<div>
<h1>{user.userId}</h1>
<img src={user.avatar_url} width={100} alt={"github avatar"} />
<p>{user.login}</p>
</div>
))}
</React.Fragment>
);
}
return null;
}
You have to map each user to the expected output component. Using a map will prevent the previous behaviour because if no elements are present in the array, it will not map anything and return an empty component instead of an error.
If data is not supposed to be an array, then you shouldn't use a map nor initialize the state with an empty array because before running the fetch it will try to render the component and fail.
Is this something like you u want?
I removed the backslash after https://api.github.com/users*here*.
I set the data in useEffect hooks, in your example you didnt do it.
And mapped the array in data, it shows all the github users with
images and names.
.
function GitHubUser() {
const [data, setData] = useState([]);
useEffect(() => {
fetch(`https://api.github.com/users`) // removed the backslash here
.then(res => res.json())
.then(data => setData(data)) // changed this line
.catch(console.error);
}, []);
console.log(data)
return (
<div>
{data.map((item, key) => <> // Mapping through the array here
<h1 key={key}>{item.id}</h1>
<img src={item.avatar_url} width={100} alt={"github avatar"}/>
<p>{item.login}</p>
</>
)}
</div>
);
}

Why is this promise returning an [object Promise] and not the value?

I thought I fully understood promises, but I'm stumped on this. I realize I should use async/await, but for this example I specifically want to only use .then().
When I do this:
const theJson = fetch(
`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`
)
.then( quoteTypeResponse => quoteTypeResponse.json() )
.then( data => {
console.log(data)
return data
});
the console.log(data) in the last function prints the JSON as expected, but when I try to console.log(theJson), the returned value, it prints [object Promise].. Why is this?
I was able to get the data outside of the function using react's useState/useEffect but not with just a vanilla global variable. I'm not trying to solve anything, but just want to understand why this does not work.
export default function App() {
let globalVar;
const [theQuote, setTheQuote] = useState({});
useEffect(() => {
fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`)
.then(quoteTypeResponse => quoteTypeResponse.json())
.then(quoteType =>
fetch(
'https://programming-quotes-api.herokuapp.com/quotes/' +
quoteType.type
)
)
.then(quoteResponse => {
return quoteResponse.json();
})
.then(quote => {
setTheQuote({ quote: quote.en, author: quote.author });
globalVar = quote.author;
});
}, []);
return (
<div id="app">
<h1>{theQuote.quote}</h1> // renders
<h2>{theQuote.author}</h2> // renders
<h3>globalVar: {globalVar}</h3> // undefined
</div>
);
}
Because your second .then() is inside the first then(), so theJson is a Promise<T>. The nice thing about Promise<T> is that you can move an inner .then() call up a level and it will still work:
Change it from this:
const theJson = fetch(
`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`
)
.then( quoteTypeResponse => quoteTypeResponse.json().then( data => {
console.log(data)
return data
} )
);
To this:
const theJson = fetch(
`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`
)
.then( quoteTypeResponse => quoteTypeResponse.json() )
.then( data => {
console.log(data)
return data
});
But ideally, use async function so you can have this considerably simpler code instead:
const resp = await fetch( `https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json` );
const data = await resp.json();
console.log( data );
#pushkin left a good link explaining the differences between async/await and using .then(), but basically, the value returned by the then() is only available within that block.
Promises cheat sheet: https://levelup.gitconnected.com/async-await-vs-promises-4fe98d11038f
fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`)
.then(quoteTypeResponse => quoteTypeResponse.json())
.then(quoteType =>
fetch(
'https://programming-quotes-api.herokuapp.com/quotes/' + quoteType.type
)
)
.then(quoteResponse => {
return quoteResponse.json();
})
.then(quote => {
console.log(`q:${util.inspect(quote)}`);
document.getElementById('app').innerHTML = quote.en;
});

Component nesting in react with ES6 syntax

When working on a name card generator app, trying to extract information from address object (https://jsonplaceholder.typicode.com/users). Was told the best way to present the text is to put them in separate components, and . Now I am having troubles piecing the two components together. The code is down below.
(Complete set of new code will be appreciated!)
import React, { useState, useEffect } from 'react';
const Namecard = ({ name, email, address }) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
</div>
);
};
const Address = ({ street }) => {
return <h1>{street}</h1>;
};
function App() {
const [identis, setIdenti] = useState([]);
useEffect(() => {
getIdenti();
}, []);
const getIdenti = async () => {
const acquired = await fetch(`https://jsonplaceholder.typicode.com/users`);
const data = await acquired.json();
setIdenti(data);
};
return (
<div>
{identis.map(identi => (
<Namecard name={identi.name} email={identi.email}>
<Address street={identi.address.city} />
</Namecard>
))}
</div>
);
}
export default App;
So with the current code, the output only includes name and email. Nothing is shown from the address object.
Namecard needs to explicitly render its children, otherwise they are not rendered:
const Namecard = ({name,email,children}) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
{children}
</div>
)
}
You use Address component as a children of Namecard component, so you should tell Namecard component that use this children component and render in his body.
For example you could rewrite Namecard component like that:
const Namecard = ({name, email, address, children}) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
{children}
</div>
)
};
and as a children our component render <Address street={identi.address.city}/>
Or you could rewrite like that: render Address component inside Namecard:
const Namecard = ({name, email, address}) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
<Address street={address.city}/>
</div>
)
};
const Address = ({street}) => <h1>{street}</h1>;
function App() {
const [identis, setIdenti] = useState([]);
useEffect(() => {
getIdenti();
}, []
);
const getIdenti = async () => {
const acquired = await fetch(`https://jsonplaceholder.typicode.com/users`);
const data = await acquired.json();
setIdenti(data);
}
return (
<div>
{identis.map(identi => (
<Namecard
name={identi.name}
email={identi.email}
address={identi.address}
/>
))}
</div>
)
}

React Native flatlist specific data

Im requiring data from a local json file just for test purposes (On a ideal world im going to fetch data from a remote url) this json file is an array with 8 objects, but I need the flatlist just to render the first 3, how can I do that?
My code:
import extratoData from "./extratoData.json"
export default function Body () {
const [data, setData] = useState([])
useEffect(() => {setData(extratoData)}, [])
return(
<FlatList
data={extratoData}
renderItem={({item}) => <ExtratoRenderItem title={item.title} amount={item.amount} date={item.date} time={item.time} cashback={item.cashBack}/>}
keyExtractor={(item, index) => index.toString()}
/>
)
You can just use the Array.prototype.slice() method.
var firstThree = extratoData.slice(0, 3);