How can I loop through a nested loop and show data - reactjs

Hey I am trying to show data from this api data
{
"status": "success",
"data": [
{
"id": 1,
"created_at": "2022-12-20T15:20:42.000000Z",
"updated_at": "2022-12-20T15:20:42.000000Z",
"lp_campaign_id": "61c158df57694",
"lp_campaign_key": "MQkGFrhcbtx4BDzq87TP",
"lp_supplier_id": "asdasd",
"first_name": "Test",
"last_name": "test",
"phone": "+1234567893",
"email": "test#gmail.com",
"zip_code": "2356"
},
{
"id": 2,
"created_at": "2022-12-20T15:20:57.000000Z",
"updated_at": "2022-12-20T15:20:57.000000Z",
"lp_campaign_id": "61c158df57694",
"lp_campaign_key": "MQkGFrhcbtx4BDzq87TP",
"lp_supplier_id": "asdasd",
"first_name": "Test",
"last_name": "test",
"phone": "+1234567893",
"email": "test#gmail.com",
"zip_code": "2356"
},
{
"id": 3,
"created_at": "2022-12-20T15:22:18.000000Z",
"updated_at": "2022-12-20T15:22:18.000000Z",
"lp_campaign_id": "61c158df57694",
"lp_campaign_key": "MQkGFrhcbtx4BDzq87TP",
"lp_supplier_id": "asdasd",
"first_name": "Test",
"last_name": "test",
"phone": "+1234567893",
"email": "test#gmail.com",
"zip_code": "2356"
}
]
}
It has nested loop I guess. So how can I show data using react js. I tried using react js but failed to show data using my code I shown below.
Here what I tried
let [leads, setLeads] = useState([])
const url = "http://127.0.0.1:8000/api/data"
useEffect(() => {
fetch(url).then(response => {
console.log(response)
})
.then(result => {
setLeads(result)
})
.catch(e => {
console.log(e)
})
})
{
leads ?
leads.map(
(lead) => {
return (
<tr className="hover:bg-gray-100 p-3">
<td>{lead.data.created_at}</td>
<td>123</td>
<td>123</td>
<td>123</td>
<td>123</td>
</tr>
)
}
):
<>Data Not Found</>
}
I am not familiar with react js at all. Som I have no idea about it. What is the easy way to show the data?

You can try this code, so you can get the response and use the array in data property in the response.
let [leads, setLeads] = useState([]);
const url = "http://127.0.0.1:8000/api/data";
useEffect(() => {
fetch(url)
.then((response) =>
(response.json())
)
.then((result) => {
setLeads(result.data);
})
.catch((e) => {
console.log(e);
});
},[]);
return leads ? (
leads.map((lead, index) => (
<tr className="hover:bg-gray-100 p-3" key={lead.id}>
<td>{lead.created_at}</td>
<td>{lead.updated_at}</td>
<td>123</td>
<td>123</td>
<td>123</td>
</tr>
))
) : (
<>Data Not Found</>
);

Related

How to parse a nested json file in typescript (.tsx)?

I'm new to typescript and looking for a way to parse this nested json data given below and display the following info after parsing:
Date: 2022-10-27T16:28:01Z
Typename": Asset,
PolicyId: 12345678abcdef,
Asset Name: 12345678abc,
Quantity:5000,
Output txHash: 1212345678abcdef,
Output txHash: 1212345678abcdef1234
{
"transactions": [
{
"__typename": "Transaction",
"includedAt": "2022-10-27T16:28:01Z",
"mint": [
{
"__typename": "Token",
"asset": {
"__typename": "Asset",
"policyId": "12345678abcdef",
"assetName": "12345678abc",
"name": null
},
"quantity": "5000"
}
],
"outputs": [
{
"__typename": "TransactionOutput",
"txHash": "1212345678abcdef",
"value": "1500000",
"tokens": [
{
"__typename": "Token",
"asset": {
"__typename": "Asset",
"policyId": "12345678abcdef",
"assetName": "12345678abc"
},
"quantity": "5000"
}
]
},
{
"__typename": "TransactionOutput",
"txHash": "12bcd12345678abcdef1234",
"value": "9998312015",
"tokens": []
}
]
}
]
}
`
I tried the following code:
const myJSON = JSON.stringify(data, null, 2);
const myArray = JSON.parse(myJSON);
and was able to display the Date:
const DisplayData1 = myArray.transactions.map(
(info:any) => {
return(
<tr>
<td>{info.includedAt}</td>
</tr>
)
}
)
I'm not able to proceed due to the nested nature of the json file and my lack of familiarity with tsx. All help appreciated. Thanks.
Need to add the nested loop to show data.
Also in order to access keys starting with -, use a square bracket instead of the . operator. like obj['__typename']
const DisplayData1 = myArray.transactions.map(
(info:any) => {
return(
<tr>
<td>{info.includedAt}</td>
{
info.mint.map((i) => {
return (
<td>{i['__typename']}</td>
<td>{i.quantity}</td>
<td>{i.asset.policyId}</td> // access `asset` object
)
})
}
</tr>
)
}
)

Having problems parsing json complex data in react js. Map error

App.js
I am facing this issue file error - Uncaught TypeError: items.data.map is not a function. I have tried some other options but did not work. I cant seem to find what I am doing wrong.
.then((res) => res.json())
.then((json) => {
this.setState({
items: json,
DataisLoaded: true
});
})
}
render() {
const { DataisLoaded, items } = this.state;
if (!DataisLoaded) return <div>
<h1> Loading data ... </h1> </div> ;
return (
<div className = "App">
<h1> Fetch data from an api in react </h1> {
items.data.map((item) => (
<ol key = { item.data} >
Continents: {item.data[0]}
</ol>
))
}
</div>
);
}
}
export default App;
JSON Data
Nested API data from json data type.
{
"data": {
"data": [
{
"project_id": "xxxx",
"title": "xxx34",
"description": "xxx23",
"expense": 1699126,
"budget": 6418516,
"country": "xxx",
"sector": [
{
"name": "Accelerate structural transformations",
"code": "18"
}
],
"sdg": [
{
"name": "Peace, justice, and strong institutions",
"id": "16"
}
],
"signature_solution": [
{
"name": "Strengthen effective, inclusive and accountable governance",
"id": "2"
}
],
"donor": [
"Australian DFAT",
"GLOBAL FUND TO FIGHT AIDS, TUBERCULOSIS",
"UNITED NATIONS DEVELOPMENT PRO"
],
"marker": [
"Hows",
"Joint Programme",
"Partner",
"Whos",
"COVID-19 Response"
]
},
{
],
"links": {
"next": null,
"previous": null
},
"count": 44
},
"status": 200,
"success": true
}
I tried data.data.map but still facing the same error. What am I doing wrong here?
Firstly, the TypeError you got is syntax error. The implementation of an arrow function must follow by curly brackets
items.data.map((item) => (
<ol key = { item.data} >
Continents: {item.data[0]}
</ol>
))
to
items.data.map((item) => {
<ol key = { item.data} >
Continents: {item.data[0]}
</ol>
})
Secondly, items you are mapping is a nest of JSON object - key: value pair. It's not suitable for mapping.
The mapping iterator or iterating an array is perfect when used to retrieve
data from a sequence item have the same or similar structure.
E.g:
const arr = [{"id": "1", "name": "a"}, {"id": "2", "name": "b"}, {"id": "3", "name": "c"}];
arr.map((item) => {
console.log(item.id);
console.log(item.name);
})
You should pretreat your data first.

How to map a nested JSON response in React

I have to map the nested JSON result in React. The below one is the response I got as response from backend API.
{
"id": 2,
"name": "sanjna",
"email": "vv#gmail.com",
"address": "iiiii, hhh",
"gender": "1",
"tagline": "Friendly to all",
"description": "4 years experience in programming",
"languages": "English ",
"key_skills": [
{
"id": 1,
"name": "RUBY ON RAILS, HTML, BOOTSTRAP, JQUERY, REACT",
"relevant_experience": "4"
},
{
"id": 2,
"name": "ruby",
"relevant_experience": "2"
}
],
"certifications": [
{
"id": 1,
"name": "MCA",
"institution_name": "vvv unversity",
"certification_date": "20-12-2020",
"image": null
},
{
"id": 2,
"name": "HTML training",
"institution_name": "nnn unversity",
"certification_date": "20-12-2022",
"image": null
}
],
"educations": [
{
"id": 1,
"qualification": "MCA",
"course": "Masters Degree PG",
"institute": "kkk",
"ins_location": "jjjj",
"passing_year": "2015"
}
]
}
This is my React code to get this response
const [singleUserDetail, setsingleUserDetail] = React.useState('');
let logged_user_id = job_seeker.actable_id;
const getsingleUserDetails = (logged_user_id) => {
axios
.get(`http://localhost:3001/users/${logged_user_id}`, { withCredentials: true })
.then((response) => {
const singleUserDetail = response.data;
setsingleUserDetail(response.data)
console.log(response.data); //prints the above JSON results in console
})
.catch((error) => {
console.log(" error", error);
});
};
React.useEffect(() => {
getsingleUserDetails(logged_user_id);
}, [logged_user_id]);
When I prints {singleUserDetail.name} it gives me result sanjna
{singleUserDetail.email} it gives me result vvv#gmail.com
{singleUserDetail. address} it gives me result iiiii, hhh. from my above JSON result
But how to print keyskills, certifications and educations here with mapping. I'm a beginner in React.
Youu can do something like this, my example is very simple,but you can complicate this as much as you need, with conditions or loops in loops.
<div>
{singleUserDetail.name},{singleUserDetail.email},{singleUserDetail.address},{singleUserDetail.gender},{singleUserDetail.tagline},{singleUserDetail.description}, {singleUserDetail.languages}
</div>
{singleUserDetail.key_skills.map((skill)=>{
return(
<div key={skill.id}>
{skill.name}:{skill.relevant_experience}
</div>
);
})}
{singleUserDetail.certifications.map((certification)=>{
return(
<div key={certification.id}>
{certification.name},{certification.institution_name},{certification.certification_date}
</div>
);
})}
{singleUserDetail.educations.map((education)=>{
return(
<div key={education.id}>
{education.qualification},{education.course},{education.institute}
</div>
);
})}
For more information, React documentation

how to decrement count value that is in a nested array within a reducer

I need to increment, and decrement on each click(its for a like button). I figured out the logic to increment a like value, but how would i go about decrementing the value ?
The count is pretty much the length of the array, how many likes for that particular post/image.
So here is the logic that increments the like value, and this works, it will increment to infinity, which is not what i want. Im looking for is the reducer logic that will take care of the decrement value, just as the POST_LIKE_SUCCESS does
console.log( newState.images.find(image => image.id === action.data).likes)
data structure as followed
Data structure.
{
"id": 154,
"image_title": "iiisdd",
"img_url": "https://res*******",
"created_at": "2019-07-18T19:44:49.805Z",
"updated_at": "2019-07-18T19:44:49.805Z",
"user_id": 1,
"user": {
"id": 1,
"googleId": null,
"username": "E*******",
"password": "$***********JwCO",
"email": "e******",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
},
"comments": [
{
"id": 51,
"comment_body": "owls life",
"created_at": "2019-07-18T20:04:51.484Z",
"updated_at": "2019-07-18T20:04:51.484Z",
"user_id": 8,
"image_id": 154,
"user": {
"id": 8,
"googleId": null,
"username": "guest",
"password": "$************",
"email": "***********l.com",
"created_at": "2019-07-18T20:04:34.315Z",
"updated_at": "2019-07-18T20:04:34.315Z"
}
},
{
"id": 52,
"comment_body": "dadad",
"created_at": "2019-07-19T20:16:40.103Z",
"updated_at": "2019-07-19T20:16:40.103Z",
"user_id": 1,
"image_id": 154,
"user": {
"id": 1,
"googleId": null,
"username": "**********",
"password": "$*********O",
"email": "e*******m",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
}
},
{
"id": 53,
"comment_body": "test",
"created_at": "2019-07-21T22:12:44.729Z",
"updated_at": "2019-07-21T22:12:44.729Z",
"user_id": 1,
"image_id": 154,
"user": {
"id": 1,
"googleId": null,
"username": "E******d",
"password": "$********4WjO",
"email": "********",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
}
}
],
"likes": [
{
"id": 24,
"user_id": 2,
"image_id": 154,
"created_at": "2019-07-22T19:26:27.034Z",
"deleted_at": "2019-07-22T19:26:27.034Z",
"restored_at": "2019-07-22T19:26:27.034Z",
"updated_at": "2019-07-22T19:26:27.034Z"
},
{
"id": 77,
"user_id": 1,
"image_id": 154,
"created_at": "2019-07-23T02:55:31.051Z",
"deleted_at": "2019-07-23T02:55:31.051Z",
"restored_at": "2019-07-23T02:55:31.051Z",
"updated_at": "2019-07-23T02:55:31.051Z"
}
]
}
I want to delete the like, similar to redux boilerplate counter like this.
state - 1
reducer
import {
UPLOAD_IMAGE_SUCCESS,
POST_COMMENT_SUCCESS,
DELETE_IMAGE_FAILURE,
FETCH_IMAGES_SUCCESS,
DISLIKE_POST_SUCCESS,
POST_COMMENT,
POST_LIKE,
POST_LIKE_SUCCESS,
POST_LIKE_FAILURE,
DELETE_IMAGE_SUCCESS,
} from '../actions/types';
const initialState = {
images: [],
likedByuser: false,
};
export default (state = initialState, action) => {
switch (action.type) {
case FETCH_IMAGES_SUCCESS:
return {
...state,
images: action.images,
};
.....
case DELETE_IMAGE_SUCCESS:
// console.log(action)
return {
...state,
images: state.images.filter(img => img.id !== action.data),
};
case DELETE_IMAGE_FAILURE:
return {
...state,
error: action.error,
};
case POST_LIKE_SUCCESS:
console.log(action.data);
const newState = { ...state }; // here I am trying to shallow copy the existing state;
const existingLikesOfPost = newState.images.find(image => image.id === action.data).likes;
console.log(existingLikesOfPost)
newState.images.find(image => image.id === action.data).likes = [...existingLikesOfPost, action.newLikeObject]; // using this approach I got some code duplication so I suggested the first approach of using **push** method of array.
// console.log(newState)
return newState;
case DISLIKE_POST_SUCCESS:
console.log(action.data)
// working on logic that will decrement
return{
...state - 1
}
default:
return state;
}
};
console.log(action.data)
{
"type": "POST_LIKE",
"data": {
"id": 154,
}
}
express backend logic
router.post('/like/:id', (req, res) => {
const { id } = req.params;
if (id !== null || 'undefined') {
Image.forge({ id })
.fetch({ withRelated: ['user', 'comments', 'likes'] })
.then((likes) => {
const like = likes.toJSON();
// console.log(like.likes);
const existingUserlikes = like.likes.map(user => user.user_id);
// checking to see if a user already liked his own post
// if existing user does not have user id, user can like post,
// else if user already like this post wont be able to.
const newLike = new Likes({
image_id: id,
user_id: req.user.id
});
if (existingUserlikes.includes(req.user.id)) {
// !newLike do not create a new row of likes if like from this user already exists
if (!newLike) {
Likes.forge().where({ user_id: req.user.id, image_id: id }).destroy();
}
return Likes.forge().where({user_id: req.user.id, image_id: id }).fetch()
.then((like) => like.destroy()
.then( () => res.json({ error: true, data: { message: 'like deleted' } })));
}
newLike.save().then(like => res.status(200).json({ status: 'You liked this post', like: newLike }));
});
}
});
I feel like you are complicating things. Personally, I wouldn't structure my data like that. Deeply nested objects should be avoided. You can instead have several objects that are linked to each other. Also, I would have the post ids as object keys, so when I want to update a specific post, I just need to
return {
...state,
[action.id]: {
...state[action.id],
...action.newData,
}
}
In your case, I would just filter out the user id that disliked the post:
...
case DISLIKE_POST_SUCCESS:
const newState = { ...state };
const predicate = ({ id }) => id === action.data;
const existingLikes = newState.images.find(predicate).likes;
// You would have to pass userId as an action payload as I'm assuming you are deleting
// the likes based on the userId.
const newLikes = existingLikes.filter(({ user_id }) => user_id !== action.userId);
newState.images.find(predicate).likes = newLikes;
The easiest thing would be to use an immutability-helper. This enables you to update an object immutable without worrying about the whole object.
You could update it like this:
return update(state, {
likes: {$remove: [action.id]}
});
If you change your like object later on, you don't have to change this part of the code, because it will only update the mentioned data.

Map through Array object stored in state

Im trying to access data from an API and render the results. Im storing each object in a separate state and im trying to map through each state, however this throws the following Error.
My code is:
state = {
events: [],
items: [],
isLoading: true
}
// fetchData = () => {
componentDidMount() {
const url = 'http://www.mocky.io/v2/5c8673f0340000981789c0da'
axios.get(url).then(response => {
this.setState({ items: response.data, isLoading: false, events: response.data[0] })
console.log(this.state.events)
})
}
render() {
return(
<div>
<div>
<h1>26/2</h1>
<ul>
{ this.state.events.map(event => (<li>{event.activity}</li>)) }
</ul>
</div>
<div>
<h1>27/2</h1>
<ul>
</ul>
</div>
</div>
)
}
}
API structure:
[
{
"id": 1,
"activity": "lunch",
"startDate": "2019-02-26 12:00",
"endDate": "2019-02-26 13:00",
"location": "Lagerhuset"
},
{
"id": 2,
"activity": "meeting",
"startDate": "2019-02-26 22:00",
"endDate": "2019-02-27 07:00",
"location": "online"
},
{
"id": 3,
"activity": "meeting",
"startDate": "2019-02-26 10:00",
"endDate": "2019-02-26 12:00",
"location": "Lagerhuset"
}
]
Now im wondering if what I'm trying to achieve even is possible? And if so, what am I doing wrong? Thanks.
items contain the array of items. events just contain the first item which is an object. Hence the map fails.
Either use :
{this.state.items.map(event => (
<li>{event.activity}</li>
))}
or this :
<li>{this.state.events.activity}</li>

Resources