React Js create option list from array - reactjs

I'm trying to create an options for my select list:
getMarkOptions: function () {
var options = this.props.renderProps;
return options.map(function (mark, i) {
return <option
key={i}
value={mark}>
{mark}
</option>
});
},
render: function () {
console.log('mark editor ' + this.props);
var selectedMark = this.props.value,
row = this.props.data,
highlightCurrentDay = this.props.highlight ? 'edit-select__currentDay':'';
return (
<select
value={selectedMark}
ref="selectMark"
className={"edit-select form-control " + highlightCurrentDay}
onChange={this.onChange}
>
{this.getMarkOptions()}
</select>
);
}
Data:
var marks = [
{"id": 1, "caption": "/", "code": "/", "meaning": "Present (AM)", "isStandardCode": true},
{"id": 2, "caption": "\\", "code": "\\", "meaning": "Present (PM)", "isStandardCode": true},
{"id": 3, "caption": "B", "code": "B", "meaning": "Educated off site", "isStandardCode": true},
{"id": 4, "caption": "C", "code": "C", "meaning": "Other Authorised Circumstances", "isStandardCode": true},
{"id": 5, "caption": "D", "code": "D", "meaning": "Dual registration", "isStandardCode": true}
];
I keep getting the error:
Unhandled rejection Invariant Violation: Objects are not valid as a React child (found: object with keys {id, caption, code, meaning, isStandardCode}). 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.
Can anyone help?

The invariant is pointing out that the child to the option tag is an object - <option>{mark}</option> - but should be a valid child e.g. string, int, React Component, etc - <option>{mark.meaning}</option>
Try something like this:
return options.map(function (mark, i) {
return <option
key={mark.id}
value={mark.code}>
{mark.meaning}
</option>
});

Related

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.

React - Realm result as list of object

I want to add a property to result query of realm and i did something like this
findAllSelected() {
let result = super.findAll()
result = result.map(item => {
return {...item, isSelected: false}
})
return result
}
This is my findAll method
findAll () {
return RealmSchemas.objects(this.schema)
}
But later i found it the result from findAll is looks like this
{"0": {"contact_id": 7, "id": 1, "isArchived": false, "isPinned":
true, "message": Test 1", "name": "User 1", "time": "14.10 PM", "unread": 1}, "1":
{"contact_id": 8, "id": 2, "isArchived": false, "isPinned": true,
"message": "Test 2", "name": "User 2",
"time": "11.21 AM", "unread": 2}}
My question is how do i add property to array likes that? Or other way around how do i convert result of my query to list of object so i can use map to add a property?
You may try using this:
let result = super.findAll()
for (const propertyName in result){
result[propertyName].isSelected = false
}
It gets all the property names in the object and adding a new property isSelected for each iteration.

How to modify a complex JSON Object in using Immutable

I have below JSON and wanted to update the value depending on Aid, Bid and Cid using Immutable.js
e.g.
Below input provided.
Aid= A, Bid = 1, Cid= 4, NewValue = 'FOUR'
If above input is provided the value "One" needs to be changed to "FOUR"
let sampleJson = {
Aid: 'A', detail:"sample", list: [
{
"Bid": "1",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "One"
},
{
"name": "Group A",
"Cid": "41",
"value": "1"
},
]
},
{
"Bid": "2",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
]
};
I was able to access the value using below code. How can i return the entire JSON with updated value?
let variale = Immutable.fromJS(sampleJson).
getIn(['list']).
find(allocation => allocation.get("Bid") === "1").
getIn(['group']).
find(fun => fun.get("Cid") === "4").set('value',"FOUR");
Anyone has any suggestions on how to resolve this problem?
I think you can try to do this like so:
let immutable = Immutable.fromJS(sampleJson);
immutable = immutable.setIn(['list', 0, 'group', 0, 'value'], 'FOUR');
This monstrosity is how I would do it:
const newData = originalData.update('list', list => {
const itemIndex = list.findIndex(item => item.get('Bid') === '2');
return list.update(itemIndex, listItem => {
return listItem.update('group', groupList => {
const groupIndex = list.findIndex(group => group.get('Cid') === '4');
return groupList.update(groupIndex, group => {
return group.set('value', 'FOUR');
});
});
});
});
https://jsbin.com/latupo/7/edit?html,js,console
Personally I stopped using Immutable, I always found it a bit painful (not to mention those docs!). I now use redux and good old cloning to not mutate state. Less performant in theory but if you've got nothing that runs over a few milliseconds anyway, save yourself the trouble...

How to display nested objects and or arrays in angular 2

I am getting json data from the back-end(api). And i want to display this with ngFor. I got an error message like: "Cannot find a differ supporting object '[object Object]'" from the console.
later I tried this:
#Pipe({
name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform{
transform(map: {}, args: any[] = null): any {
if (!map)
return null;
return Object.keys(map)
.map((key) => ({ 'key': key, 'value': map[key] }));
}
}
and then in my view:
<li *ngFor="let detail of getEventDetails | mapToIterable">
Creator Email: {{detail.creator.email}}
</li>
this time i didn't get an error but there is no display values of {{detail.creator.email}}
Data from back-end
{
"banner_image": null,
"categories": [],
"creator": {
"email": "email#email.com",
"first_name": "Prince",
"gender": true,
"id": 15,
"last_name": "Odame",
"subscribed_categories": [],
"watchlist": []
},
"creator_id": 15,
"description": "Learn how to install solar panels in 3 days and make real money all your lifetime",
"faqs": [],
"id": 6,
"is_verified": true,
"max_tickets_per_user": 1,
"shows": [
{
"address": "Engineering Auditorium, College of Engineering, KNUST, Kumasi",
"city": "Kumasi",
"country": "Ghana",
"end_time": "2016-08-03T14:30:00+00:00",
"event_id": 6,
"id": 5,
"is_online": false,
"start_time": "2016-08-01T08:30:00+00:00",
"state": "Ashanti",
"ticket_types": [],
"venue": "Engineering Auditorium"
}
],
"tags": [],
"title": "Solar Panels Installation Workshop"
}
Thanks in advance
You probably just want to do this:
<li>Creator Email: {{getEventDetails.creator.email}}</li>
And for the arrays:
<li *ngFor="let show of getEventDetails?.shows">
Show ID: {{show.id}}
</li>

JSON array iteration skips first element - NodeJS

Ive got this JSON markup:
"Categories": [
{"name": "a", "id": "1"},
{"name": "b", "id": "2"},
{"name": "c", "id": "3"},
{"name":"d", "id": "4"},
{"name":"e", "id": "5"},
{"name": "f", "id": "6"},
{"name": "g", "id": "7"},
{"name": "h", "id": "8"}
]
Ive got a setInterval going over each of these categories and making a new Promise for each one.
For some unknown reason, it always skips the first element and exists with an out of bounds exception
var i = 0;
var id = setInterval(function(){
if (i == categories.length){
clearInterval(id);
}
client.itemSearch({
category: categories[i].id,
catName: categories.name,
}).then(function(results){
console.log("From category - " + categories[i].name + "\n" +
"Title: " + results[0].Title);
},function(err) {
console.log("error at " + categories[i].name);
});
i+=1;
}, 1000);
The problem is that you're referencing i in your promise callbacks and i changes every second. So your callbacks are being executed sometime in the future when i === categories.length, which would be an invalid index.
Since you already have a closure, just store the current category object in a variable outside of your promise callbacks and reference that instead.
You're also letting the function continue when i === categories.length which will cause an invalid index access.
Here's an example of a solution that fixes the aforementioned issues:
var i = 0;
var id = setInterval(function() {
if (i === categories.length) {
clearInterval(id);
return;
}
var category = categories[i];
client.itemSearch({
category: category.id,
catName: category.name,
}).then(function(results) {
console.log("From category - " + category.name + "\n" +
"Title: " + results[0].Title);
}, function(err) {
console.log("error at " + category.name);
});
i += 1;
}, 1000);
Lastly, you originally had catName: categories.name but I changed it to catName: category.name as I assumed that may have been your original intention.

Resources