react native functional component useState not Updating - javascript

this is my state object .
const [track_record, setTrackRecord] = useState({
id: '1',
name: '',
date: '',
time: '',
start_address: '',
end_address: '',
distance: '0',
duration: '0',
avg_speed: '0',
max_speed: '0',
min_speed: '0',
coordinates: [],
});
here is the function where I am updating it.
setTrackRecord(prev => ({
...prev,
name: `Track ${tracks.length + 1}`,
date: moment().format('DD-MM-YYYY'),
time: moment().format('hh:mm'),
}));
every time I console it ut has the same values.

You can set prev data as it is with track_record and append other data with it's updated value like below:
setTrackRecord({
...track_record,
name: `Track ${tracks.length + 1}`,
date: moment().format('DD-MM-YYYY'),
time: moment().format('hh:mm'),
});

Related

Adding object to nested array using firebase, nextjs

I'm using nextjs, firebase to build my project, the project idea is a hybrid project management, the user is able to create a project with many boards and save tasks inside it:
UI of the board
I want to save the board in this way:
screen shot from Firebase
The code:
Here is how board array and project states looks:
const [projectFields, setProjectFields] = useState({
title: '',
details: '',
date: '',
});
const [boardFields, setboardFields] = useState([
{
title: '',
type: '',
columns: [
{ name: "backlog" },
{ name: "In progress" },
{ name: "In review" }
]
},
]);
sendProject function:
const sendProject = async () => {
if (loading) return;
setLoading(true);
const docRef = await addDoc(collection(db, "projects"), {
id: session.user.uid,
projectDetails: projectFields,
boards: boardFields,
timestamp: serverTimestamp(),
});
setLoading(false);
setProjectFields({
title: '',
details: '',
date: '',
})
setboardFields({
title: '',
type: '',
columns: [{}]
})
};
sendTask function, which is update the "boards" in the doc in firebase wrongly:
const sendTask = async () => {
if (loading) return;
setLoading(true);
let object = {
id: '1',
priority: tasksFields.priority,
title: tasksFields.title,
date: tasksFields.date,
details: tasksFields.details,
chat: '0',
attachment: '0'
}
const taskRef = doc(db, "projects", projectId ?? "1");
const newBoards = [...project.boards];
newBoards[boardIndex] = {
...newBoards[boardIndex],
columns: {
...newBoards[boardIndex].columns[columnIndex],
tasks: [...newBoards[boardIndex].columns[columnIndex].tasks, object]
},
}
await updateDoc(taskRef, {
...project,
boards: newBoards,
});
setLoading(false);
setTasksFields(
{
id: '',
priority: '',
title: '',
details: '',
date: '',
attachment: '0',
}
)
};
here is the result after updating the doc:
wrong database schema picture
I don't know how to update it correctly, any help please? thank you all
I found the solution ๐Ÿ‘‡:
Updated sendTask function:
const sendTask = async () => {
if (loading) return;
setLoading(true);
let object = {
id: '1',
priority: tasksFields.priority,
title: tasksFields.title,
date: tasksFields.date,
details: tasksFields.details,
chat: '0',
attachment: '0'
}
const taskRef = doc(db, "projects", projectId ?? "1");
const newBoard = {...project.boards};
const newColumn = [...project.boards[boardIndex].columns];
newColumn[columnIndex] = {
...newColumn[columnIndex],
tasks: [...newColumn[columnIndex].tasks, object]
};
newBoard[boardIndex] = {...newBoard[boardIndex], columns: newColumn};
await updateDoc(taskRef, {
...project,
boards: newBoard,
});
setLoading(false);
setTasksFields(
{
id: '',
priority: '',
title: '',
details: '',
date: '',
attachment: '0',
}
)
};
};

How do I update array inside object in redux

I have an array I'm writing a code for redux now.
const initialState = [{ id: '1', title: '', description: '' }];
I would like to update that array like this
[{ id: '1', title: '', description: '' },{ id: '2', title: '', description: '' }];
and after copying I want to update the copy one of id to '2'
here is what I tried
case COPY_QUESTION: {
const copyQuestion = state.find(question => question.id === action.payload)
copyQuestion?.id = (state.length + 1).toString()
return [...state, copyQuestion];
}
it didn't work for me. if I try to change id, the 0 index changes too at the same time. like this
[{ id: '2', title: '', description: '' },{ id: '2', title: '', description: '' }];
I would really appreciate your help thanks for reading this question.
JavaScript handels Objects by reference and therefore โ€™findโ€™ only returns the address in memory of the already existing object, which you then manipulate.
You have to clone your object first, e.g. using the spread operator (not for deep clones):
const originalQuestion = state.find(question => question.id === action.payload)
const copyQuestion = { ...originalQuestion }
Have a look at this SO question for more context and possibilities.
Something like this should work:
const initialState = [{ id: '1', title: '', description: '' }];
const copyInitialState = [...initialState]
copyInitialState.push({ id: parseInt(copyInitialState[copyInitialState.length - 1].id, 10) + 1, title: '', description: '' })
//setState
copyInitialState is then equal to:
[
{
id:"1",
title:"",
description:""
},
{
id:2,
title:"",
description:""
}
]

JS: Group an array of object by specific field into section list

I have such data:
const data = [
{
id: '1',
name: 'River',
address: 'Terminal A',
type: 'OTHER',
code: null,
targetArrivalStep: 30,
disabled: true,
},
{
id: '2',
name: 'Afer',
address: 'Afer train station',
type: 'TRAIN_STATION',
code: 'MTS',
targetArrivalStep: 0,
disabled: false,
},
{
id: '3',
name: 'Fidel',
address: 'HHH',
type: 'OTHER',
code: '',
targetArrivalStep: 0,
disabled: false,
},
{
id: '5',
name: 'Train station',
address: 'Patrick str.',
type: 'TRAIN_STATION',
code: null,
targetArrivalStep: 0,
disabled: false,
},
{
id: '7',
name: 'qqq',
address: 'qqq',
type: 'BUS_STATION',
code: null,
targetArrivalStep: 60,
disabled: false,
},
];
I need to group it by type.
Here's the desired output:
const res = [
{
type: 'OTHER',
data: [
{
id: '1',
name: 'River',
address: 'Terminal A',
type: 'OTHER',
code: null,
targetArrivalStep: 30,
disabled: true,
},
{
id: '3',
name: 'Fidel',
address: 'HHH',
type: 'OTHER',
code: '',
targetArrivalStep: 0,
disabled: false,
},
],
},
{
type: 'TRAIN_STATION',
data: [
{
id: '2',
name: 'Afer',
address: 'Afer train station',
type: 'TRAIN_STATION',
code: 'MTS',
targetArrivalStep: 0,
disabled: false,
},
{
id: '5',
name: 'Train station',
address: 'Patrick str.',
type: 'TRAIN_STATION',
code: null,
targetArrivalStep: 0,
disabled: false,
},
],
},
{
type: 'BUS_STATION',
data: [
{
id: '7',
name: 'qqq',
address: 'qqq',
type: 'BUS_STATION',
code: null,
targetArrivalStep: 60,
disabled: false,
},
],
},
];
Here's my solution:
const result = data.reduce((c, item) => {
c[item.type] = c[item.type] || [];
c[item.type].push(item);
return c;
}, {});
I don't like the mutation of reduce arguments. Is there any other way to solve this task?
As stated in the comments, mutating the accumulator is perfectly reasonable: it is freshly created for this specific function call and only gets altered internally and without interruption. Seen from the outside, your solution is a pure function with no side effects.
For the sake of the example though, this is how you could rewrite your solution in a declarative fashion using some fancy destructuring magic:
const result = data.reduce((c, item) => ({...c, [item.type]:[...c[item.type] ?? [], item]}), {});
Explanation:
const result = data.reduce(
(c, item) => ({ // Return a new object
...c, // Copy the previous object into it
[item.type]: [ // Overwrite the current type group
...(c[item.type] ?? []), // Copy the old items of that group (or an empty array)
item // Add the current item
] }),
{}
);
It's pretty clear to me however that your original solution is the more readable and thus superior one.

parse nested javascript array

I have this array
air_content: '',
compaction_method: 1,
concrete_cylinders: [
{
id: '',
specimen_name: 'A',
mould_number: '',
curing: 1,
age: 7
},
{
id: '',
specimen_name: 'A',
mould_number: '',
curing: 1,
age: 7
},
{
id: '',
specimen_name: 'A',
mould_number: '',
curing: 1,
age: 7
}
]
I'm trying to parse them when i post the data ( formik modifies them back to text so i am required to parse them as int for my backend )
My post looks like this ( this works except for the nested objects i want them parsed as integer also )
axios.post('http://localhost:8123/samples/concrete', {
air_content: parseFloat(air_content),
compaction_method: parseInt(compaction_method),
concrete_cylinders
});
the psuedo/My best try of the code of what I'm trying to do is the below
axios.post('http://localhost:8123/samples/concrete', {
air_content: parseFloat(air_content),
compaction_method: parseInt(compaction_method),
concrete_cylinders: {
[concrete_cylinders.id]: parseInt(concrete_cylinders.id),
[concrete_cylinders.curing]: parseInt(concrete_cylinders.curing)
}
});
Thankyou for assistance
before calling axios.post you'll need to
concrete_cylinders.forEach(x => {
x.id = parseInt(x.id);
x.curing = parseInt(c.curing);
});
or, if you really want, you can do it like
axios.post('http://localhost:8123/samples/concrete', {
air_content: parseFloat(air_content),
compaction_method: parseInt(compaction_method),
concrete_cylinders: concrete_cylinders.map(x => {
x.id = parseInt(x.id);
x.curing = parseInt(c.curing);
return x;
});
});
Here's a version using the newer spread syntax:
const concrete_cylinders = [
{
id: '',
specimen_name: 'A',
mould_number: '',
curing: '1',
age: '7'
},
{
id: '',
specimen_name: 'A',
mould_number: '',
curing: '1',
age: '7'
},
{
id: '',
specimen_name: 'A',
mould_number: '',
curing: '1',
age: '7'
}
]
const result = concrete_cylinders.map(o => ({
...o,
...{
curing: parseInt(o.curing),
age: parseInt(o.age)
}
}));
console.log(result);
You could always try using forEach on the array before posting. So for example...
pojo = {
air_content: '',
compaction_method: 1,
concrete_cylinders: [
{
id: '3',
specimen_name: 'A',
mould_number: '',
curing: '1',
age: 7
},
{
id: '3',
specimen_name: 'A',
mould_number: '',
curing: '1',
age: 7
},
{
id: '3',
specimen_name: 'A',
mould_number: '',
curing: '1',
age: 7
}
]
}
pojo.concrete_cylinders.forEach(e => {
e.id = parseFloat(e.id)
e.curing = parseInt(e.curing)
//...anything else you want to change before posting
})
Then pass the object to your axios.post
axios.post('http://localhost:8123/samples/concrete', pojo);
I'm sure there's a way to do this in less lines, but this should solve your problem.

Update the property of a array of object in react js

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 ?

Categories