How to add the array to useState correctly? - reactjs

I define a state like this:
const [user, setUser] = useState(
[] as { userId: string; userHabbitList: string[] }[],
)
My API will be like this:
userList = [
{
"id": "1",
"userHabbit": [
{
"userHabbitId": "1"
},
{
"userHabbitId": "2"
}
]
},
{
"id": "2",
"userHabbit": [
{
"userHabbitId": "3"
},
{
"userHabbitId": "4"
}
]
}
]
Here is my working:
setUser(
userList.map( e =>
({
userId: e.id,
userHabbitList: e.userHabbit.map( u => u.userHabbitId)
})
)
)
However the userHabbitList still empty,
Here is my expect result:
[
{userId: "1", userHabbitList: ["1","2"]},
{userId: "2", userHabbitList: ["3","4"]}
]

Related

How to delete new array in react native object

I have following array
[{
"games1": [{
"playername": "1"
}]
},
{
"games2": [{
"playername": "1"
},
{
"playername": "2"
}
]
}
]
I want to delete games2 from the array how to do this
I want this type of output
[{
"games1": [{
"playername": "1"
}]
}
}]
Use filter to filter what you want to keep.
Like this:
const arr = [
{
games1: [
{
playername: '1',
},
],
},
{
games2: [
{
playername: '1',
},
{
playername: '2',
},
],
},
]
// keep games1
const newArr = arr.filter((r) => r.games1)
console.log(newArr)
// remove games2, keep others
const newArr2 = arr.filter((r) => !r.games2)
console.log(newArr2)
output would be
[
{
"games1": [
{
"playername": "1"
}
]
}
]
const NewArray = array.filter((item) => item !== "games2");
console.log(NewArray)
Try the below code:
let final = x.filter(x=>{
let c = Object.getOwnPropertyNames(x)
return c!="games2"
})
here the output of the 'final' is :
[{
"games1": [{
"playername": "1"
}]
}
}]

How to update nested array of objects in ReactJS

I have an array of object like this:
const tempobj = [
{
id: "1",
fanimate: [
{
id: "111",
animate: "xyz",
},
],
},];
Now I want to add more animations inside this array, such that each object gets added in the fanimate such that:
const tempobj = [
{
id: "1",
fanimate: [
{
id: "111",
animate: "xyz",
},
{
id: "222",
animate: "def",
},
],
},];
I tried using the hook useState, but I am getting undefined results
const tempobj = [
{
id: "1",
fanimate: [
{
id: "111",
animate: "xyz",
},
],
}];
const modified = tempobj.map(temp => {
const newtemp = {
id: temp.id,
fanimate: [...temp.fanimate, {id:"222", animate:"def"}]
}
return newtemp;
})
console.log(modified);
You could just spread all the places
const tempObj = {
id:'1',
fan:[
{
id:'2',
animate:'xyz'
}
]
}
console.log(tempObj)
const newtest={...testObj,fan:[...testObj.fan, {id:'3', animate:'tuz'}]}
console.log(newtest)
Try this:
const tempobj = [
{
id: "1",
fanimate: [
{
id: "111",
animate: "xyz"
}
]
}
];
const [state, setState] = useState(tempobj);
function updateArray(newItem) {
setState(
state.map((item) => ({ ...item, fanimate: [...item.fanimate, newItem] }))
);
}
You can push the newItem to the original fanimate array using spread operator, everytime a new item is added, the original array data is copied by ...item.fanimate:
{ ...item, fanimate: [...item.fanimate, newItem] }
BTW the naming of tempobj really should be tempArr or tempArray.
A working sandbox

How to create nested array in realm without key(React Native)

{
"a": [
[
{
"_id": "57e55b64016c3551c025abc1",
"title": "Main Campus"
},
{
"_id": "5810e2e27064497f74ad4874",
"title": "Ahm Campus"
},
{
"_id": "5d5d2633a1d0680620ac3cce",
"title": "Baroda"
},
{
"_id": "5d5d3af3a1d0680620ac3ef8",
"title": "India"
}
],
[
{
"_id": "57e55b64016c3551c025abc1",
"title": "Main Campus"
},
{
"_id": "5810e2e27064497f74ad4874",
"title": "Ahm Campus"
},
{
"_id": "5d5d2633a1d0680620ac3cce",
"title": "Baroda"
},
{
"_id": "5d5d3af3a1d0680620ac3ef8",
"title": "India"
}
]
]
}
How to create the schema in the realm(React native) for this type of JSON object. I tried all possible ways but did not found any specific solution. Basically, it is a nested array where the second array does not have any specific key(I tried with key it works fine but I want to do it without adding key).
You can use something like:
const ParentSchema = {
name: "parent",
properties: {
key: "string",
values: "Value[]"
}
};
const ValueSchema = {
name: "Value",
embedded: true,
properties: {
_id: "string",
title: "string"
}
};
You can insert objects like:
realm.write(() => {
realm.create("Parent", { key: "a", values: [
{ _id: "57e55b64016c3551c025abc1", title: "Main Campus" },
{ _id: "5810e2e27064497f74ad4874", title: "Ahm Campus" }
]
});
});
Documentation: https://docs.mongodb.com/realm/node/data-model
As of now there is no way to insert direct value in Realm database without key so for now we need to modify data and then we can store in following schema.
const ParentSchema = {
name: "parent",
properties: {
a: "level[]"
}
};
const level = {
name: 'level',
properties: {
level: 'sites[]'
}
}
const sites = {
name: 'sites',
properties: {
sites: 'site[]'
}
}
const site = {
name: 'site',
properties: {
title: 'string?',
_id: 'string?',
version: 'int?',
}
}
Data modification need to done like following.
var a = {
level: []
}
data.a.map((Site, index) => {
const sites = []
Site.map((s) => { sites.push(s)})
a.level.push({sites})
})

How to get the minimum value by react js

In the code below, I am trying to run {this.renderCost(data,'mina')} with react js. I would like to obtain the minimum value of total using the code below, but total of an object that value of nameis Equal to for example mina(or other name because it will be changed).
I tried the following :
Firstly push the value of total using indents.push(elem.total), the expected output for this part is [2000,1000] and then get minimum value of array by Math.min(...indents),the expected output for this part is [1000] but the function doesn't work.
const data = [
{
"obj": {
"no": "1",
"info": [
{
"name": "maya"
},
{
"name": "mina"
}
],
"total":"2000"
}
},
{
"obj": {
"no": "2",
"info": [
{
"name": "maya"
}
],
"total":"1000"
}
},
{
"obj": {
"no": "3",
"info": [
{
"name": "mina"
},
{
"name": "Mike"
}
],
"total":"1000"
}
}
]
renderCost(data,name){
let indents = [];
data.map((elem) => {
this.renderTotal(elem,name,indents)
})
}
renderTotal(elem,name,indents){
for(let i = 0 ; i < elem.info.length;i++){
if (elem.info[i].name == name){
indents.push(elem.total)
}
return (
Math.min(...indents)
)
}
}
The data structure you're working with isn't ideal for this particular search however you can get to your answer with the following:
const minTotalByName = (data, name) => {
const totals = data
.filter(x =>
x.obj.info.find(y => y.name === name)
).map(x => x.obj.total);
return Math.min(...totals);
}
const min = minTotalByName(data, "mina"); // 1000
To find the min value for the name you can use below code:
const { useState } = React;
function App() {
const [name, setName] = useState("");
const filtered = data
.filter(obj => obj.obj.info.some(n => n.name === name))
.map(obj => Number(obj.obj.total));
const min = filtered.length !== 0 ? Math.min(...filtered) : "";
return (
<div>
<input onChange={(e) => setName(e.target.value)} />
<div>The result is: {min}</div>
</div>
);
}
const data = [
{
obj: {
no: "1",
info: [ { name: "maya" }, { name: "mina" } ],
total: "2000"
}
},
{
obj: {
no: "2",
info: [ { name: "maya" } ],
total: "1000"
}
},
{
obj: {
no: "3",
info: [ { name: "maya" }, { name: "Mike" } ],
total: "1000"
}
}
];
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

How to search and filter in array of objects on setState

I'm trying to create a search based on an array of objects with react which data is in this format:
const data = [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
},
{
"name": "Mango Sticky Rice",
"desc": "Mango, rice, milk",
"allergens": ""
}
]
}
]
I stored this data inside useState declaration to be able to render accordingly on data chnage:
const [filteredBySearch, setFilteredBySearch] = useState(data)
I have an input where we can type anything and set inside useState declaration.
Goal:
If I type in my input:
"Jui"
Output should be:
console.log(filteredBySearch)
/* output:
[
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : []
}
]*/
Exemple 2:
If I type in my input:
"Orange banana"
Output should be:
console.log(filteredBySearch)
/* output: [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
}
]
}
]*/
I've try creating a new object with map and filter and set it with setFilteredBySearch, but I can't get anything, even creating this new object.
This the full component:
import Card from '../components/Card'
import React, { useState } from 'react';
export default function IndexPage({ data, search }) {
//search is the result of input value set on a useState
//Filter categoriesFoods by search
const [FilteredBySearch, setFilteredBySearch] = useState(data)
return (
<div className="main-content">
<div className="card-container">
{
FilteredBySearch.map(function(el, i) {
return (
<div key={i}>
<h2 className="category" id={Object.keys(el)}>{Object.keys(el)}</h2>
{
el[Object.keys(el)].map (function(itm,index){
return <Card key={index} infoItem={itm}/>
})
}
</div>
)
})
}
</div>
<style jsx>{`...`}</style>
</div>
)}
Any idea for me ?
Thanks a lot for your guidance!
I think this is what you are looking for. I have created below utilities for filtering as per your requirement.
const dataObj = [
{
'category 1': [
{
name: 'Orange',
desc: 'juice, orange, Water',
},
{
name: 'Ananas',
desc: 'juice, ananas, water',
},
],
},
{
'category 2': [
{
name: 'Banana Split',
desc: 'Banana, ice cream, chocolat, topping',
allergens: 'nuts',
},
{
name: 'Mango Sticky Rice',
desc: 'Mango, rice, milk',
allergens: '',
},
],
},
]
const checkIfInputMatches = (input, desc) => input.toLowerCase().split(" ").some(o => desc.toLowerCase().includes(o))
const filterByInput = (data, input) => {
let finalResult = [];
data.forEach(d => {
let keys = Object.keys(d);
let values = Object.values(d);
finalResult = [...finalResult, ...values.map((obj, index) => {
let result = obj.filter(o => checkIfInputMatches(input, o.desc))
return {[keys[index]]: result}
})]
})
return finalResult
}
console.log(filterByInput(dataObj, 'JUI'))
console.log(filterByInput(dataObj, "orange"))
console.log(filterByInput(dataObj, "rice"))
console.log(filterByInput(dataObj, "Orange banana"))
Hope this helps.

Resources