Update the property of a array of object in react js - javascript

I am new to the react-redux.
Here I have an object which is like,
const initialState = {
Low: [
{
id: 0,
technologyId: 0,
technology: '',
type: '',
count: '',
allowded: 6,
level: 'EASY'
}
],
Medium: [
{
id: 0,
technologyId: 0,
technology: '',
type: '',
count: '',
allowded: 7,
level: 'MEDIUM'
}
],
High: [
{
id: 0,
technologyId: 0,
technology: '',
type: '',
count: '',
allowded: 7,
level: 'TOUGH'
}
]
}
Now, this value is set it in the reducer I am taking it as a props.
Now, onchnage here the object property gets change from one of these obj.
So, Here the way I am updating it is ,
onChange(event, tobeupdated, id, type, noc, data) {
let newData = { ...this.props.data };
if (newData) {
let data = newData[type].map((object, index) => {
if (object.id === id) {
object[tobeupdated] = event.target.value;
});
}
}
So,Here will I be updating the existing object ?
Or is there any another way ?
What I tried was,
{...object, [tobeupdated]: event.target.value}
it is giving the compile time errors .
How can I resolve this ?

Related

Advanced filtering nested elements in TypeScript/JavaScript

Given the following structure and data:
interface GrandChild {
id: number,
values: Array<string>,
}
interface Child {
id: number,
subItems: Array<GrandChild>
}
interface Foo {
items: Array<Child>
}
const data: Foo = {
items: [
{ id: 1, subItems: [ { id: 10, values: ['10', '100'] }, { id: 11, values: ['11', '110', '1100'] } ] },
{ id: 2, subItems: [ { id: 20, values: ['REMOVE', 'REMOVE'] }, { id: 21, values: ['REMOVE'] } ] },
{ id: 3, subItems: [ { id: 30, values: ['REMOVE'] }, { id: 31, values: ['REMOVE'] }, { id: 32, values: ['REMOVE', '32'] } ] },
]
};
How can I use the Array's methods (filter, map, some, etc.) to achieve the following result?
const expected: Foo = {
items: [
{ id: 1, subItems: [ { id: 10, values: ['10', '100'] }, { id: 11, values: ['11', '110', '1100'] } ] },
{ id: 3, subItems: [ { id: 32, values: ['32'] } ] },
]
}
So far, I filtered the resulting data, removing the undesired elements, as following:
const filteredData: Foo = {
...data,
items: data.items.map(item => ({
...item,
subItems: item.subItems.map(subItem => ({
...subItem,
values: subItem.values.filter(value => value !== 'REMOVE')
}))
}))
}
Resulting:
{
items: [
{ id: 1, subItems: [ { id: 10, values: ['10', '100'] }, { id: 11, values: ['11', '110', '1100'] } ] },
{ id: 2, subItems: [ { id: 20, values: [] }, { id: 21, values: [] } ] },
{ id: 3, subItems: [ { id: 30, values: [] }, { id: 31, values: [] }, { id: 32, values: ['32'] } ] },
]
};
But, I cannot figure a way out to remove the empty subItems elements without looping through the result.
You can check online the above code here.
If you really want to do it just with filter and map, add a filter after each of your maps to remove subItems that have an empty values array and to remove items that have an empty subItems array:
const filteredData = {
...data,
items: data.items
.map((item) => ({
...item,
subItems: item.subItems
.map((subItem) => ({
...subItem,
values: subItem.values.filter((value) => value !== "REMOVE"),
}))
.filter(({ values }) => values.length > 0), // ***
}))
.filter(({subItems}) => subItems.length > 0), // ***
};
But:
When I have map followed by filter, I always ask myself if the data is large enough that I should avoid making multiple passes through it.
When I'm doing lots of nesting of map calls and such, I always ask myself if it would be clearer when reading the code later to use simpler, smaller loops.
Here's what you might do if answering "yes" to either or both of those questions:
const filteredData: Foo = {
...data,
items: [],
};
for (const item of data.items) {
const subItems: Array<GrandChild> = [];
for (const subItem of item.subItems) {
const values = subItem.values.filter((value) => value !== "REMOVE");
if (values.length) {
subItems.push({
...subItem,
values,
});
}
}
if (subItems.length > 0) {
filteredData.items.push({
...item,
subItems,
});
}
}

how to simplify the length of the state in react js

import { OrderSummary } from "#/services/order/data";
Below is my state declaration
let [orderSummary, setOrderSummary] = useState<OrderSummaryResponse>({
Id: 0,
TableId: 0,
TableName: '',
MerchantId: 0,
StoreId: 0,
StoreName: '',
BrandName: '',
IsUnifyQR: false,
Discount: 0,
ServiceCharge: 0,
GST: 0,
RoundingAdjustment: 0,
TotalAmount: 0,
SubTotalAmount: 0,
ServiceChargeAmount: 0,
GSTAmount: 0,
CreatedAt: '',
Items: [
{
MerchantId: 0,
StoreId: 0,
StoreName: '',
ItemId: 0,
ProductId: 0,
ProductName: '',
TotalAmount: 0,
Quantity: 0,
Note: '',
Choices: [
{
OptionSelectedName: '',
ProductOptionId: 0,
OptionSelected: null,
MultiOptionsSelected: null,
OneChoiceWithValueSelected: {
OptionSelected: 0,
Quantity: 0,
Price: 0,
},
MultioptionWithValueSelected: [],
},
],
},
],
Categories: [''],
});
if I have a few usestate like above, my code looks very lengthy how to simplify that.
getting error if I use like this
let [orderSummary, setOrderSummary] = useState<OrderSummary>({})
let [orderSummary, setOrderSummary] = useState<OrderSummary>({} as any)
You can use type like this:
let [orderSummary, setOrderSummary] = useState<OrderSummary | null>(null)
And when you want to use orderSummary. You can add optional chaining like this:
orderSummary?.StoreId

Filtering an array of objects Vue

I have an array of objects and Im trying to filter by matching ids
//Vehicle is added to quote
function filterByID(item) {
return item.id === 1;
}
this.vehicle = this.data.filter(filterByID);
data is as follows:
data: [
0: {
id: 0,
name: name
},
1: {
id: 1,
name: name
},
2: {
id: 2,
name: name
}
]
Im getting an empty error when I check the vehicle part
Are you using it like this:
const data = [
{
id: 0,
name: '',
},
{
id: 1,
name: '',
},
{
id: 2,
name: '',
},
];
function filterByID(item) {
return item.id === 1;
}
console.log(data.filter(filterByID)); // output: [{ "id": 1, "name": "" }]
You don't always need to define a separate function, you can use an arrow function, as below.
const data = [{
id: 0,
name: name
},
{
id: 1,
name: name
},
{
id: 2,
name: name
}
]
const vehicle = data.filter(item => item.id === 1);
console.log(vehicle);
This works fine in pure JS, it looks like it might be an issue with the lifecycle or state of your application. Use console.log to make sure that this.data is what you expect it to be

State is not getting initialized to the initial state of reducer

I am new to the react redux . Here, what I am doing is ,
const initialState = {
Low: [
{
id: 0,
technologyId: 0,
technology: '',
level: 'EASY'
}
],
Medium: [
{
id: 0,
technologyId: 0,
technology: '',
level: 'MEDIUM'
}
],
High: [
{
id: 0,
technologyId: 0,
technology: '',
level: 'TOUGH'
}
]
}
Now,In my reducer ,
export default function QuizData(state = initialState, action) {
switch (action.type) {
case QUIZ_DATA:
return {
...state,
Low: action.data,
error: false,
}
case RESET_QUIZ_CRITERIA: {
console.log("intial state is ", ...state);
return {
...state
}
Now, here what happens is after some manipulations, this objects gets changes with every key is having some values. like,
So, This gets changed.
{
Low: [
{
id: 0,
technologyId: 11,
technology: 'xsxs',
level: 'EASY'
}
],
Medium: [
{
id: 0,
technologyId: 22,
technology: 'swwsw',
level: 'MEDIUM'
}
],
High: [
{
id: 0,
technologyId: 110,
technology: 'xsxsx',
level: 'TOUGH'
}
]
}
for resetting my action is like ,
export function resetPreviousQuizSelectionCriteria() {
console.log("Calling this");
return {
type: RESET_QUIZ_CRITERIA
}
}
Now, what I want to do is that ,
When user clicks a button that time I want to change this to the initial state.
So that it will not have any values as it should be same as by default.
So, Can any one one suggest me the solution?
I think returning initial State should resolve the issue.
case RESET_QUIZ_CRITERIA: {
console.log("intial state is ", ...state);
return {
...initialState
}
try this if it works.

Update the redux state in the reducer having array of objects

I am new to the react-redux.
I do have an object which is like,
const initialState = {
Low: [
{
id: 0,
technologyId: 0,
technology: '',
level: 'EASY'
}
],
Medium: [
{
id: 0,
technologyId: 0,
technology: '',
level: 'MEDIUM'
}
],
High: [
{
id: 0,
technologyId: 0,
technology: '',
level: 'TOUGH'
}
]
}
Now,
export default function QuizData(state = initialState, action) {
switch (action.type) {
case QUIZ_DATA:
return {
...state,
Low: action.data,
error: false,
}
case RESET_SETUP_QUIZ: {
console.log("intial state is ", ...state);
return {
...state
}
Now, here what happens is after some manipulations, this objects gets changes with every key is having some values. like,
{
Low: [
{
id: 0,
technologyId: 11,
technology: 'xsxs',
level: 'EASY'
}
],
Medium: [
{
id: 0,
technologyId: 22,
technology: 'swwsw',
level: 'MEDIUM'
}
],
High: [
{
id: 0,
technologyId: 110,
technology: 'xsxsx',
level: 'TOUGH'
}
]
}
So, This gets changed.Now, what I want to do is that ,
When user clicks a button that time I want to change this to the initial state.
So that it will not have any values as it should be same as by default.
SO, what I tried it
return {
initalState
}
But here, initial state is also having the same values.
So, I am not getting a way to make it to the initial level.
Can one help me with this ?
Because you use the original state object and return a modified version of it (i.e. you do affect your initialState).
You must create a copy of the state in your reducer, for example
case QUIZ_DATA:
return Object.assign(
{},
state,
{
Low: action.data,
error: false
}
)
case RESET_SETUP_QUIZ: {
return Object.assign(
{},
state
)
}
You have dedicated librairies like immutablejs to handle this
(https://redux.js.org/recipes/usingimmutablejs)

Categories