Reading JSON data with axios and React - javascript

So I created this backend json response.
{
"places": [
{
"location": {
"lat": 40.3714624,
"lng": 21.7614661
},
"_id": "5f9bb2ff4fc07350c317500c",
"title": "Alcazar Park",
"description": "A lovely park.",
"image": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Empire_State_Building_%28aerial_view%29.jpg/400px-Empire_State_Building_%28aerial_view%29.jpg",
"creator": "5f9bb2ee4fc07350c317500b",
"__v": 0,
"id": "5f9bb2ff4fc07350c317500c"
},
{
"location": {
"lat": 40.3714624,
"lng": 21.7614661
},
"_id": "5f9bb4f9d92cd5541f5922fc",
"title": "Alcazar Park",
"description": "A beautiful park.",
"image": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Empire_State_Building_%28aerial_view%29.jpg/400px-Empire_State_Building_%28aerial_view%29.jpg",
"creator": "5f9bb2ee4fc07350c317500b",
"__v": 0,
"id": "5f9bb4f9d92cd5541f5922fc"
},
{
"location": {
"lat": 40.3714624,
"lng": 21.7614661
},
"_id": "5f9bb632d92cd5541f5922fd",
"title": "Train station of Larisa",
"description": "An old but cool train station",
"image": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Empire_State_Building_%28aerial_view%29.jpg/400px-Empire_State_Building_%28aerial_view%29.jpg",
"creator": "5f9bb2ee4fc07350c317500b",
"__v": 0,
"id": "5f9bb632d92cd5541f5922fd"
}
]
}
Now I want to display in a list just the title of each place in the array. Here is my code
for that in React
const DataFetching = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
axios
.get('http://localhost:5000/api/places/user/5f9bb2ee4fc07350c317500b')
.then(res => {
console.log(res)
setPosts(res.data);
})
.catch((err) => {
console.log(err)
})
}, []);
return(
<div>
<ul>
{
posts.map(post => <li key={post.id}>{post.title}</li>)
}
</ul>
</div>
)
}
export default DataFetching;
However, I am getting this error
How can I fix it?
TypeError: posts.map is not a function
Thanks,
Theo

Try this:
setPosts(res.data.places)
posts?.map(post => <li key={post.id}>{post.title}
or:
setPosts(res.data)
posts.places?.map(post => <li key={post.id}>{post.title}

Related

How to get common value in Object Array in JavaScript

const data = {
"games": [
{
"id": "828de9122149499183df39c6ae2dd3ab",
"developer_id": "885911",
"game_name": "Minecraft",
"first_release": "2011-18-11",
"website": "https://www.minecraft.net/en-us"
},
{
"id": "61ee6f196c58afc9c1f78831",
"developer_id": "810637",
"game_name": "Fortnite",
"first_release": "2017-21-07",
"website": "https://www.epicgames.com/fortnite/en-US/home"
},
],
"developers": [
{
"id": "885911",
"name": "Mojang Studios",
"country": "US",
"website": "http://www.mojang.com",
},
{
"id": "750245",
"name": "God of War",
"country": "SE",
"website": "https://sms.playstation.com",
},
] };
I have json data like this. I want to display data like if developer_id = 885911(from games array) then print id(from developers array) and if the both are same then I want to print the name.(Mojang studios) and so on like games website etc. How can I do that?
This sample code will show you the developer of each game, if it's found:
const data = {
"games": [
{
"id": "828de9122149499183df39c6ae2dd3ab",
"developer_id": "885911",
"game_name": "Minecraft",
"first_release": "2011-18-11",
"website": "https://www.minecraft.net/en-us"
},
{
"id": "61ee6f196c58afc9c1f78831",
"developer_id": "810637",
"game_name": "Fortnite",
"first_release": "2017-21-07",
"website": "https://www.epicgames.com/fortnite/en-US/home"
},
],
"developers": [
{
"id": "885911",
"name": "Mojang Studios",
"country": "US",
"website": "http://www.mojang.com",
},
{
"id": "750245",
"name": "God of War",
"country": "SE",
"website": "https://sms.playstation.com",
},
] };
const gameDevelopers = data.games.map(g => ({
game: g.game_name,
developer: data.developers.find(d => d.id === g.developer_id)?.name || "No matching developer found"
}));
console.log(gameDevelopers)
What did you exactly need? i don't understand . But you can get value Mojang Studios
console.log(data.developers[0].name)
If you need all developer id then you can use
console.log(data.developers.map(data=>{
console.log(data.id)
}))
If you need the id where name is Mojang Studios
console.log(data.developers.map(data=>{
if(data.name == "Mojang Studios"){
console.log(data.id)
}
}))

React table from object with objects

I got 2 types of json API and i want to display them in table. First one has following structure:
data1:[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere#april.biz",
"address":"Gwenborough",
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": "Romaguera-Crona"
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna#melissa.tv",
"address": "Wisokyburgh",
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": "Deckow-Crist"
}
]
Second:
data2:[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere#april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna#melissa.tv",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
}
]
My Table component works for first type of data (data1) and creates a table. But obviously for second (data2) type i'm getting error. I tried a lot of things and i can't get access to address and geo fields and can't display them in table.
Table component:
export default class Table extends React.Component {
constructor(props){
super(props);
this.getHeader = this.getHeader.bind(this);
this.getRowsData = this.getRowsData.bind(this);
this.getKeys = this.getKeys.bind(this);
}
getKeys = function(){
return Object.keys(this.props.data[0]);
}
getHeader = function(){
var keys = this.getKeys();
return keys.map((key, index)=>{
return <th key={key}>{key.toUpperCase()}</th>
})
}
getRowsData = function(){
var items = this.props.data;
var keys = this.getKeys();
return items.map((row, index)=>{
return <tr key={index}><RenderRow key={index} data={row} keys={keys}/></tr>
})
}
render() {
console.log('Get keys:', this.getKeys());
return (
<div>
<table>
<thead>
<tr>{this.getHeader()}</tr>
</thead>
<tbody>
{this.getRowsData()}
</tbody>
</table>
</div>
);
}
}
const RenderRow = (props) =>{
return props.keys.map((key, index)=>{
return <td key={props.data[key]}>{props.data[key]}</td>
})
}
const uniqueArr = [...data1, ...data2]
const formatData = uniqueArr.map((item) => {
if(typeof item.address === "object"){
return {
...item,
address: item.address.street.concat(", ", item.address.city),
company: item.company ? item.company.name : ""
}
}
return item
})

How to use selected value in React dropdown as api url id?

I want to render into table specific data from url with id taken after user select the needed value so here is my code:
fetching data for select options:
export default function Dashboard() {
const [value, setValue] = useState();
const [students, setstudents] = useState([]);
useEffect(() => {
const fetchStudents = async () => {
try {
const resp = await Axios({
method: "GET",
url: "https://jsonplaceholder.typicode.com/users",
headers: {
"Content-Type": "application/json",
},
});
setstudents(resp.data);
} catch (err) {}
};
fetchStudents();
}, []);
const classes = useStyles();
const [selected,setselected]=useState();
const options = students.map(s => ({
"value" : s.id,
"label" : s.username
}))
const handleChange = (event) => {
setselected(event.value);
};
now fetching data in dashboard function for selected value:
const [tabl, settabl] = useState([]);
useEffect(() => {
const fetchtabl = async () => {
try {
const resp = await Axios({
method: "GET",
url: "https://jsonplaceholder.typicode.com/users"+{selected},
headers: {
"Content-Type": "application/json",
},
});
settabl(resp.data.surveys);
} catch (err) {
console.log(err);
}
};
fetchtabl();
}, []);
const getTableData = (tabl) => {
return tabl.map((tab) => [
tab.id,
tab.name,
tab.username,
]);
};
now render data in return:
Select the course:
<Select options={options} onChange={handleChange}/>
<Table
tableHead={["Course Code", "Course Name", "Survey Link"]}
tableData={getTableData(tabl)}
tableHeaderColor="primary"
/>
but nothing appear after select the value needed how can i fix it and does react allow to use selected value like this?
data
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere#april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna#melissa.tv",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"email": "Nathan#yesenia.net",
"address": {
"street": "Douglas Extension",
"suite": "Suite 847",
"city": "McKenziehaven",
"zipcode": "59590-4157",
"geo": {
"lat": "-68.6102",
"lng": "-47.0653"
}
},
"phone": "1-463-123-4447",
"website": "ramiro.info",
"company": {
"name": "Romaguera-Jacobson",
"catchPhrase": "Face to face bifurcated interface",
"bs": "e-enable strategic applications"
}
},
So based on the conversation in the comment section the value is there in selected. Then the only problem is useEffect is not triggered on change because of empty dependency array.
I suggest few modifications in your code:
Add to the dependency array selected as [selected] which will trigger the function once you have change on that state.
Check for null or undefined values in order not to concatenate without value.
Also I added one extra slash into your URL after users so now it's users/.
So the URL would be at the end of the day:
`https://jsonplaceholder.typicode.com/users/${selected}`
Based on the explanation try as:
useEffect(() => {
const fetchtabl = async () => {
try {
const resp = await Axios({
method: "GET",
url: `https://jsonplaceholder.typicode.com/users/${selected}`,
headers: {
"Content-Type": "application/json",
},
});
settabl(resp.data.surveys);
} catch (err) {
console.log(err);
}
};
if (selected) {
fetchtabl();
}
}, [selected]);
+1 suggestion:
Maybe it's not related but you have in .map() an extra [] which might be not needed, so try as:
const getTableData = (tabl) => {
return tabl.map((tab) => ({
tab.id,
tab.name,
tab.username,
}));
};
In this way .map() will return an array of objects with the properties of id, name, username.

Unable to extract the array field from JSON file. Instead my code returns "{}"

I want to return (res.json) the array of chats in this model but when I am trying to do so I am getting "{}".
On the other hand, when I am printing other fields like email or first_name, I am getting the results.
However, I guess the problem is only with arrays.
I am using MongoDB to store data and Postman for requests
PLEASE HELP!
Here is my JSON model.
{
"_id": "5f0d5ea45eeeaa3730eaf96c",
"first_name": "Test_firstName",
"last_name": "Test_lastName",
"email": "test#email.com",
"password": "$2b$10$B8EDo3KkJZ9PjGveWfouM.1XhaPSx9xrM3c6Mk2HC02AUNnO99Of.",
"address": "Home",
"chats": [
{
"id": "985234e2-86c6-4375-968a-96661c37ec32",
"name": "Community",
"messages": [
{
"id": "35c7bf4d-e556-40bd-9429-16e436c599f4",
"time": "11:10",
"message": "Hi",
"sender": "user1"
},
{
"id": "a74ad9ba-44b9-43af-90a0-cf9480d9a748",
"time": "11:11",
"message": "hey",
"sender": "user2"
}
]
}
],
"createdAt": "2020-07-14T07:28:36.148Z",
"updatedAt": "2020-07-14T07:28:36.148Z",
"__v": 0
}
Here is my code to find a chat from my model.
Please have a look at the lines with "<"
const find_chat = (req, res, next) => {
let email = req.body.email;
let chatId = req.body.chatId;
User.findOne({ email: email })
.then(async (response) => {
> let x = [];
> x = response.chats;
> res.json({
> response,
> });
})
.catch((error) => {
res.json({
message: "An error occured",
});
});
};
Here is the expected output
{
[
{
"id": "35c7bf4d-e556-40bd-9429-16e436c599f4",
"time": "11:10",
"message": "Hi",
"sender": "Advait"
},
{
"id": "a74ad9ba-44b9-43af-90a0-cf9480d9a748",
"time": "11:11",
"message": "hey",
"sender": "sharma"
}
]
}
You could try as this:
const data = {
"_id": "5f0d5ea45eeeaa3730eaf96c",
"first_name": "Test_firstName",
"last_name": "Test_lastName",
"email": "test#email.com",
"password": "$2b$10$B8EDo3KkJZ9PjGveWfouM.1XhaPSx9xrM3c6Mk2HC02AUNnO99Of.",
"address": "Home",
"chats": [
{
"id": "985234e2-86c6-4375-968a-96661c37ec32",
"name": "Community",
"messages": [
{
"id": "35c7bf4d-e556-40bd-9429-16e436c599f4",
"time": "11:10",
"message": "Hi",
"sender": "user1"
},
{
"id": "a74ad9ba-44b9-43af-90a0-cf9480d9a748",
"time": "11:11",
"message": "hey",
"sender": "user2"
}
]
}
],
"createdAt": "2020-07-14T07:28:36.148Z",
"updatedAt": "2020-07-14T07:28:36.148Z",
"__v": 0
}
let messages = data.chats[0].messages;
console.log(messages)
As per the later query , change it to
let x = JSON.stringify(response.chats[0].messages);
res.json({
response});

how to group by nested properties using lodash?

I have array of objects
{
"work": [{
"_id": "5c80c5c00c253823fc443337",
"start": "2019-01-01T18:30:00.000Z",
"end": "2019-01-02T18:30:00.000Z",
"employee": {
"_id": "5c80c16e0c253823fc44332a",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890"
},
"allocation": 30
},
{
"_id": "5c80c5ef0c253823fc443339",
"start": "2018-12-31T18:30:00.000Z",
"end": "2019-09-30T18:30:00.000Z",
"employee": {
"_id": "5c80c16e0c253823fc44332a",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890"
},
"allocation": 100
},
{
"_id": "5c80c60b0c253823fc44333a",
"start": "2018-12-31T18:30:00.000Z",
"end": "2020-10-07T18:30:00.000Z",
"employee": {
"_id": "5c80c16e0c253823fc44332a",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890"
},
"allocation": 25
},
{
"_id": "5c80c65e0c253823fc44333b",
"start": "2019-01-01T18:30:00.000Z",
"end": "2019-10-04T18:30:00.000Z",
"employee": {
"_id": "5c80c1940c253823fc44332b",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890"
},
"allocation": 50
},
{
"_id": "5c80c7240c253823fc44333f",
"start": "2018-12-31T18:30:00.000Z",
"end": "2019-10-09T18:30:00.000Z",
"employee": {
"_id": "5c80c26e0c253823fc44332e",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890"
},
"allocation": 25
}
]
}
I need to convert them into
[{
"_id": "5c80c16e0c253823fc44332a",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890",
"work": [{
"_id": "5c80c5c00c253823fc443337",
"start": "2019-01-01T18:30:00.000Z",
"end": "2019-01-02T18:30:00.000Z",
"allocation": 30
}, {
"_id": "5c80c5ef0c253823fc443339",
"start": "2018-12-31T18:30:00.000Z",
"end": "2019-09-30T18:30:00.000Z",
"allocation": 100
}, {
"_id": "5c80c60b0c253823fc44333a",
"start": "2018-12-31T18:30:00.000Z",
"end": "2020-10-07T18:30:00.000Z",
"allocation": 25
}]
}, {
"_id": "5c80c1940c253823fc44332b",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890",
"work": [{
"_id": "5c80c65e0c253823fc44333b",
"start": "2019-01-01T18:30:00.000Z",
"end": "2019-10-04T18:30:00.000Z",
"allocation": 50
}]
}, {
"_id": "5c80c26e0c253823fc44332e",
"status": "active",
"location": "Chennai",
"contact_number": "1234567890",
"work": [{
"_id": "5c80c7240c253823fc44333f",
"start": "2018-12-31T18:30:00.000Z",
"end": "2019-10-09T18:30:00.000Z",
"allocation": 25
}]
}]
I have done it by partially using lodash and vanilla js and it works completely fine. but readability wise is completely bad. I want to achieve this using just lodash alone. Any help?
let ids: any = groupBy(this.project.work, function (res) {
return res.employee._id;
});
for (let id in ids) {
let tmp = [];
let employee_added = false;
ids[id].map((work) => {
if (!employee_added) {
tmp = work.employee;
tmp['work'] = [];
employee_added = true;
}
delete work.employee;
tmp['work'].push(work);
})
this.employees.push(tmp);
}
console.log(this.employees);
Hopefully, this is what you are looking for.
First group it by employee_.id
Then map each group, take employee of first one (since every group
must have one entry)
Then map all other members (and take outer part) of each group to work
(everything apart from employee object)
Here is the example below:
let works = [{"_id":"5c80c5c00c253823fc443337","start":"2019-01-01T18:30:00.000Z","end":"2019-01-02T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":30},{"_id":"5c80c5ef0c253823fc443339","start":"2018-12-31T18:30:00.000Z","end":"2019-09-30T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":100},{"_id":"5c80c60b0c253823fc44333a","start":"2018-12-31T18:30:00.000Z","end":"2020-10-07T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":25},{"_id":"5c80c65e0c253823fc44333b","start":"2019-01-01T18:30:00.000Z","end":"2019-10-04T18:30:00.000Z","employee":{"_id":"5c80c1940c253823fc44332b","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":50},{"_id":"5c80c7240c253823fc44333f","start":"2018-12-31T18:30:00.000Z","end":"2019-10-09T18:30:00.000Z","employee":{"_id":"5c80c26e0c253823fc44332e","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":25}]
let res = _(works)
.groupBy('employee._id')
.map(g => ({...g[0].employee, work: _.map(g, ({employee, ...rest}) => ({...rest}))}))
.value();
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
You can create a function that uses lodash's _.flow() that groups by the employee id, and then creates an employee object with work array:
const { flow, partialRight: pr, groupBy, map, head, get, omit } = _
const fn = flow(
pr(groupBy, 'employee._id'),
pr(map, group => ({ // create the employee objects
...get(head(group), 'employee'), // get the employee data and spread it
work: group.map(o => omit(o, 'employee')) // create the work array by removing the employee from each work object
}))
)
const data = {"work":[{"_id":"5c80c5c00c253823fc443337","start":"2019-01-01T18:30:00.000Z","end":"2019-01-02T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":30},{"_id":"5c80c5ef0c253823fc443339","start":"2018-12-31T18:30:00.000Z","end":"2019-09-30T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":100},{"_id":"5c80c60b0c253823fc44333a","start":"2018-12-31T18:30:00.000Z","end":"2020-10-07T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":25},{"_id":"5c80c65e0c253823fc44333b","start":"2019-01-01T18:30:00.000Z","end":"2019-10-04T18:30:00.000Z","employee":{"_id":"5c80c1940c253823fc44332b","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":50},{"_id":"5c80c7240c253823fc44333f","start":"2018-12-31T18:30:00.000Z","end":"2019-10-09T18:30:00.000Z","employee":{"_id":"5c80c26e0c253823fc44332e","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":25}]}
const result = fn(data.work)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
You can do it succinctly using plain JavaScript with Object.values(), Array.reduce() and desctructuring assignment:
const data = {"work":[{"_id":"5c80c5c00c253823fc443337","start":"2019-01-01T18:30:00.000Z","end":"2019-01-02T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":30},{"_id":"5c80c5ef0c253823fc443339","start":"2018-12-31T18:30:00.000Z","end":"2019-09-30T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":100},{"_id":"5c80c60b0c253823fc44333a","start":"2018-12-31T18:30:00.000Z","end":"2020-10-07T18:30:00.000Z","employee":{"_id":"5c80c16e0c253823fc44332a","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":25},{"_id":"5c80c65e0c253823fc44333b","start":"2019-01-01T18:30:00.000Z","end":"2019-10-04T18:30:00.000Z","employee":{"_id":"5c80c1940c253823fc44332b","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":50},{"_id":"5c80c7240c253823fc44333f","start":"2018-12-31T18:30:00.000Z","end":"2019-10-09T18:30:00.000Z","employee":{"_id":"5c80c26e0c253823fc44332e","status":"active","location":"Chennai","contact_number":"1234567890"},"allocation":25}]};
const result = Object.values(data.work.reduce((acc, work) => {
const { employee: { _id, ...rest }, ...job } = work;
const jobs = (acc[_id] || {}).work || [];
acc[_id] = { _id, ...rest, work: [...jobs, job] };
return acc;
}, {}));
console.log(result);

Categories