I'm working on simple CRUD example using react.JS as my frontend and I ran into a issue that's probably because of my lack of experience working with React or JavaScript in general.
This is JSON I get from my API:
[{"idnaselje":1,"naziv":"Zagreb","postanskiBroj":10000,"drzavaId":1,"drzava":{"iddrzava":1,"naziv":"Hrvatska"}},{"idnaselje":2,"naziv":"Rijeka","postanskiBroj":51000,"drzavaId":1,"drzava":{"iddrzava":1,"naziv":"Hrvatska"}},{"idnaselje":14,"naziv":"Dubrava","postanskiBroj":10040,"drzavaId":1,"drzava":{"iddrzava":1,"naziv":"Hrvatska"}},{"idnaselje":15,"naziv":"Zadar","postanskiBroj":23000,"drzavaId":1,"drzava":{"iddrzava":1,"naziv":"Hrvatska"}}]
I'm trying to map drzava.naziv to display naziv...
Here is my render method:
private renderNaseljeTable(naseljeList: NaseljeData[]) {
return <table className='table'>
<thead>
<tr>
<th></th>
<th>ID Naselje</th>
<th>Naziv</th>
<th>Postanski Broj</th>
<th>Drzava</th>
</tr>
</thead>
<tbody>
{naseljeList.map(nas =>
<tr key={nas.idnaselje}>
<td></td>
<td>{nas.idnaselje}</td>
<td>{nas.naziv}</td>
<td>{nas.postanskiBroj}</td>
<td>{nas.drzava}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(nas.idnaselje)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(nas.idnaselje)}>Delete</a>
</td>
</tr>
)}
</tbody>
</table>;
}
This is data structure of NaseljeData:
export class NaseljeData {
idnaselje: number = 0;
naziv: string = "";
postanskiBroj: string = "";
drzava: string = "";
drzavaid: number = 0;
}
My problem is how to access the Object drzava inside my array to get property naziv as string and display it?
I get the following error in the console:
Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {iddrzava, naziv}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of
FetchNaselje.
2 Answers 2
You need to change the data structure of NaseljeData to have drzava as an object instead of string. You can have this, for example:
export class DrzavaData {
iddrzava: number = 0;
naziv: string = "";
}
export class NaseljeData {
idnaselje: number = 0;
naziv: string = "";
postanskiBroj: string = "";
drzava: DrzavaData = null;
drzavaid: number = 0;
}
And then, in the render method, you can just use the dot notation to get the drzava's name (naziv):
{naseljeList.map(nas =>
<tr key={nas.idnaselje}>
<td></td>
<td>{nas.idnaselje}</td>
<td>{nas.naziv}</td>
<td>{nas.postanskiBroj}</td>
<td>{nas.drzava.naziv}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(nas.idnaselje)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(nas.idnaselje)}>Delete</a>
</td>
</tr>
)}
Comments
You can either use . notation to get the value or pass key name to drzava like I mentioned below
{naseljeList.map(nas =>
<tr key={nas.idnaselje}>
<td></td>
<td>{nas.idnaselje}</td>
<td>{nas.naziv}</td>
<td>{nas.postanskiBroj}</td>
<td>{nas.drzava && nas.drzava["naziv"]}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(nas.idnaselje)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(nas.idnaselje)}>Delete</a>
</td>
</tr>
)}
OR
{naseljeList.map(nas =>
<tr key={nas.idnaselje}>
<td></td>
<td>{nas.idnaselje}</td>
<td>{nas.naziv}</td>
<td>{nas.postanskiBroj}</td>
<td>{nas.drzava && nas.drzava.naziv}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(nas.idnaselje)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(nas.idnaselje)}>Delete</a>
</td>
</tr>
)}
Edit:
You need to change your drzava: string = "" to drzava: object = {}
export class NaseljeData {
idnaselje: number = 0;
naziv: string = "";
postanskiBroj: string = "";
drzava: object = {};
drzavaid: number = 0;
}
8 Comments
nas.drzava.naziv EDIT: nevermind, saw your edited post