Update a selected property from react state of objects with arrays - reactjs

Assume that this state has initial data like this
const [options, setOptions] = useState({
ProcessType: [
{ value: 1, label: 'Type1' }, { value: 2, label: 'Type2' }
],
ResponsibleUser: [
{ value: 1, label: 'User1' }, { value: 2, label: 'User2' }
]
});
The following function will be called again and again when a post/put called
Help me to complete the commented area as described there.
const fetchProcesses = async () => {
await axios.get(`${process.env.REACT_APP_SERVER_BASE_URL}/processes/`)
.then((result) => {
/*
I want here to clear the existing data in options.ProcessType and
map result.data as { value: result.data.id , label: result.data.name },....
and push/concat it into to options.ProcessType but i want to keep the data
inside options.ResponsibleUser unchanged.
result.data is an array of objects like this,
[
{ id: 1 , name: 'Type1', desc : 'desc1', creator: 3, status: 'active' },
{ id: 2 , name: 'Type2', desc : 'desc2', creator: 6, status: 'closed' },
.....
.....
]
*/
})
}

Here is a solution
const fetchProcesses = async () => {
await axios.get(`${process.env.REACT_APP_SERVER_BASE_URL}/processes/`)
.then((result) => {
// solution
setOptions({ResponsibleUser: [...options.ResponsibleUser], ProcessType: result.data.map(row => ({value: row.id, label: row.name}))})
})
}

Related

Why can't I push in <option> when I get the 'response.data'?

Why can't I push in my <option> when I get the response.data?
type State = {
companyManagerMap: null | Map<string, string[]>
}
useEffect(() => {
AdminListManager()
.then((response) => {
const { data } = response.data
console.log( { data });
setState((s) => ({
...s,
companyManagerMap: new Map(
Object.keys(data).map((key) => [key, data[key]])
),
}))
})
.catch(showUnexpectedError)
}, [showUnexpectedError])
data format
{"total":2,"data":[{"id":1,"name":"newspeed","contains_fields":[{"id":1,"name":"Official"}]},{"id":2,"name":"YAMAHA","contains_fields":[{"id":3,"name":"US"}]}]}
You are using your .map and Object.keys wrong
Look here at where you iterate over your Object keys properly :)
const data = {
total: 2,
data: [
{ id: 1, name: 'newspeed', contains_fields: [{ id: 1, name: 'Official' }] },
{ id: 2, name: 'YAMAHA', contains_fields: [{ id: 3, name: 'US' }] },
],
};
//now iterate over it properly
data.data.map((item) => {
Object.keys(item).map((key) => {
console.log(item[key]);
});
});
console.log will return this output
1
newspeed
[ { id: 1, name: 'Official' } ]
2
YAMAHA
[ { id: 3, name: 'US' } ]
I'm guessing you want to add the new data from your res.data to a state
So you can do something like this:
const fetchData = async () => {
try {
const res = await AdminListManager()
//do data manipulation over objects and set new state
} catch (error) {
showUnexpectedError()
}
}
useEffect(()=> {
fetchData()
}, [showUnexpectedError])

Nested filter in typescript

I have a JSON array, which looks as follows.
[
{
id: 1,
name: 'Alex',
activity: [
{
id: 'A1',
status: true
},
{
id: 'A2',
status: true
},
{
id: 'A3',
status: false
}
]
},
{
id: 2,
name: 'John',
activity: [
{
id: 'A6',
status: true
},
{
id: 'A8',
status: false
},
{
id: 'A7',
status: false
}
]
}
]
I want to get an array of activity id whose status should be true.I can achieve this with nester for or forEach loop. But here I am looking to achieve with the help of array functions like filter, map, and some.
I have already tried with the following.
let newArr=arr.filter(a=> a.activity.filter(b=> b.status).map(c=> c.id))
But I didn't get the correct answer
Expected output
['A1','A2','A6']
function filter_activity(activities) {
return activities
&& activities.length
&& activities.map(x => x.activity)
.flat().filter(activity => activity.status)
.map(x => x.id) || [];
}
Illustration
function filter_activity(activities) {
return activities &&
activities.length &&
activities.map(x => x.activity)
.flat().filter(activity => activity.status)
.map(x => x.id) || [];
}
const input = [{
id: 1,
name: 'Alex',
activity: [{
id: 'A1',
status: true
},
{
id: 'A2',
status: true
},
{
id: 'A3',
status: false
}
]
},
{
id: 2,
name: 'John',
activity: [{
id: 'A6',
status: true
},
{
id: 'A8',
status: false
},
{
id: 'A7',
status: false
}
]
}
];
console.log(filter_activity(input));
WYSIWYG => WHAT YOU SHOW IS WHAT YOU GET
let arr = json.flatMap(e => e.activity.filter(el => el.status).map(el => el.id))
let newArr=arr.map(x => x.activity)
.reduce((acc, val) => acc.concat(val), [])
.filter((activity:any) => activity.status)
.map((x:any) => x.id) || [];
I got error when using flat() and flatMap().So, I have used reduce().

How to Change Data in React

I want to create data from DATA to OPTIONS.
const DATA = [
{ name: 'aaa', id: 'happy' },
{ name: 'bbb', id: 'time' },
{ name: 'ccc', id: 'party' },
];
const OPTIONS =[{value:'aaa', label:'aaa'},
{value:'bbb', label:'bbb'},
{value:'ccc', label:'ccc'},
]
I need only name value in DATA.
so, using name value, I want to create OPTIONS.
Fuction Test(){
const DATA = [
{ name: 'aaa', id: 'happy' },
{ name: 'bbb', id: 'time' },
{ name: 'ccc', id: 'party' },
];
const OPTIONS =[{value:'aaa', label:'aaa'},
{value:'bbb', label:'bbb'},
{value:'ccc', label:'ccc'},
]
}
let newObject=[];
const createData = () => {
const arr = selectMainId.data.map(data => data.name);
arr.map(data => newObject.push({ value: data, label: data }));
console.log('newObj:', newObject);
};
console.log('newObj1:', newObject))
this case, I can get OPTIONS same data.
so, I can get newObject in createData console.
but I can't get newObject in Test console.
I don't know this issue.
Do you know effective way?
please help me.
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
Clean and simplest way:
const DATA = [
{ name: 'aaa', id: 'happy' },
{ name: 'bbb', id: 'time' },
{ name: 'ccc', id: 'party' },
];
const OPTIONS = DATA.map(x => ({value: x.name, label: x.name }));
console.log(OPTIONS);
You just need to do
const createData = (data) => {
return data.map(d => ({name: data.name, label: data.name}))
};
const option = createData(data)

Handling relational data in Zustand

I need some input from people more experienced with Zustand to share their way of managing relational state. Currently we have the following:
Let's assume we have the example entities Campaign, Elementss and their Settings. The REST API returning them is in the following format:
GET <API>/campaigns/1?incl=elements,elements.settings
{
"id":1,
"name":"Welcome Campaign",
"elements":[
{
"id":5,
"type":"heading",
"label":"Heading",
"content":"Welcome!",
"settings":[
{
"id":14,
"name":"backgroundColor",
"value":"#ffffff00"
},
{
"id":15,
"name":"color",
"value":"#ffffff00"
}
]
},
{
"id":6,
"type":"button",
"label":"Button",
"content":"Submit",
"settings":[
{
"id":16,
"name":"backgroundColor",
"value":"#ffffff00"
},
{
"id":17,
"name":"color",
"value":"#ffffff00"
},
{
"id":18,
"name":"borderRadius",
"value":"3px"
}
...
]
}
...
]
}
What we are currently doing in the Reactjs app is fetching this data, then transforming it to the following normalized format and set functions:
const useCurrentCampaignStore = create(
combine(
{
campaign: {
id: 1,
name: "Welcome Campaign"
},
elements: [
{
id: 5,
campaignId: 1,
type: "heading",
label: "Heading",
content: "Welcome!"
},
{
id: 6,
campaignId: 1,
type: "button",
label: "Button",
content: "Submit"
}
],
settings: [
{
id: 14,
elementId: 5,
name: "backgroundColor",
value: "#ffffff00"
},
{
id: 15,
elementId: 5,
name: "color",
value: "#ffffff00"
},
{
id: 16,
elementId: 6,
name: "backgroundColor",
value: "#ffffff00"
},
{
id: 17,
elementId: 6,
name: "disabled",
value: false
},
{
id: 18,
elementId: 6,
name: "borderRadius",
value: 3,
}
]
},
set => ({
updateSetting: (id: string | number, newValue: string | number | boolean) =>
set(state => {
const settings = [...state.settings];
return {
...state,
settings: settings.map(setting => {
if (setting.id == id) {
return { ...setting, value: newValue };
}
return setting;
})
};
}),
updateElementContent: (id: string | number, newValue: string) => {
set(state => {
const elements = [...state.elements];
return {
...state,
elements: elements.map(element => {
if (element.id == id) {
return { ...element, content: newValue };
}
return element;
})
};
});
}
})
)
);
I am, however, not sure this is the optimal solution, because It's rather tedious transforming all GET requests to a normalized format and then converting them back to nested objects when you want to construct either a POST, PUT or PATCH request.
So, to put it short, how do you guys design the state in your Zustand-based RESTful-API-backed React apps?

Populate my options data with react-select from API?

This doesn't seem to be working when i try to populate my data with the data i fetched from my API. I am currently fetching the data, storing it in my array called ProductsAndAirlines which i instantiated in my constructor, then I am setting the data values dynamically in my options,but currently it doesn't. It only inserts the first static value which is PBS.
Code
getProductsAndAirlines = _ => {
fetch('http://localhost:4000/allProductAndAirlineValuesInJira')
.then(res => res.json())
.then( res =>
this.setState({ ProductsAndAirlines: res.data }
))
.catch(err => console.error(err))
}
componentDidMount() {
this.getAirlines();
this.getProductsAndAirlines();
setTimeout(() => {
this.setState({ show: true });
}, 10);
}
const optionsProduct = [
ProductsAndAirlines && ProductsAndAirlines.projects && Object.keys(ProductsAndAirlines.projects).map((issue, i) => (
ProductsAndAirlines.projects[0].issuetypes[0].fields.customfield_11600.allowedValues && Object.keys(ProductsAndAirlines.projects[0].issuetypes[0].fields.customfield_11600.allowedValues ).map((product, product_index) => (
{value: ProductsAndAirlines.projects[0].issuetypes[0].fields.customfield_11600.allowedValues[product_index].value, label: ProductsAndAirlines.projects[0].issuetypes[0].fields.customfield_11600.allowedValues[product_index].value}
))
))
render(){
<Select
placeholder = {this.state.Product}
onChange={this.handleChangeProduct}
options={optionsProduct()}
/>
}
It's, probably, because your map function is wrong somehow. If you take a deep look you can check, for each key in ProductsAndAirlines.projects, the map function is returning an entirely new array. in the end, the options are being like
[
[{ value: 'PBS', label: 'PBS' },
{ value: 'Pairing', label: 'Pairing' },
{ value: 'MPP - Insight', label: 'MPP - Insight' },
{ value: 'BLISS', label: 'BLISS' },
{ value: 'Shiftlogic', label: 'Shiftlogic'}
]],
[{ value: 'PBS', label: 'PBS' },
{ value: 'Pairing', label: 'Pairing' },
{ value: 'MPP - Insight', label: 'MPP - Insight' },
{ value: 'BLISS', label: 'BLISS' },
{ value: 'Shiftlogic', label: 'Shiftlogic'}
]]
]

Resources