I would be able to update an object nested in another object in my application but i got some problems. Let's assume that the entity that I want to update is something like this:
{
{
"id": 0,
"name": "Yellow Car",
"details": {
"engine": {},
"ownerInfo": {
"name": "Luke",
"lastName": "Cage",
"email": "l.cage@hisemail.blabla"
},
},
"created": "2018-01-17",
"lastUpdate": "2020-09-03",
}
I can easily update some part of this entity in this way:
let car: Car = {
...car,
...this.form.value
};
let carUpdate: Update<Car> = {
id: car.id,
changes: car
};
this.store.dispatch(carUpdated({carUpdate}));
But in this way I can only update name, created, lastUpdate
and I can't update the nested object details
. What happens if I try to edit the detail
object now? Nothing i wanna happens.
This is the selector:
export const carUpdated = createAction(
"[Edit Car] Car Updated",
props<{carUpdate: Update<Car>}>()
);
The effect:
saveCar$ = createEffect(
() => this.actions$
.pipe(
ofType(CarActions.carUpdated),
concatMap(action => this.carService.editCar(
action.carUpdate.changes,
action.carUpdate.id
))
),
{dispatch: false}
)
The reducer:
on(CarActions.carUpdated, (state, action) =>
adapter.updateOne(action.carUpdate, state)),
The service sends to the backend the right data and it's working good without the state management. What I am doing now is retrieve the single carObject in this way in the component in the ngOnInit
car$ = this.store.pipe(
select(selectCar(id))
)
and the selector is:
export const selectCar = (id) => createSelector(
selectAllCars,
(cars: any) => cars.filter((car) => {
let filteredCar = car.id == id;
if(filteredCar) {
return car;
}
}).map(car => car)
);
and then after my edit I can use the dispatch to confirm my edit
this.store.dispatch(carUpdated({carUpdate}));
but as I said if I try to update the details object i have this
let car: Car = {
...car, // the entire car object
...this.form.value // only the details
};
let carUpdate: Update<Car> = {
id: car.id,
changes: car //the details are mixed with the car object and not inside the object itself
};
something like this:
{
"id": 0,
"name": "Yellow Car",
"engine": {},
"details": {
},
"ownerInfo": {
"name": "Luke",
"lastName": "Cage",
"email": "l.cage@hisemail.blabla"
},
"created": "2018-01-17",
"lastUpdate": "2020-09-03",
}
Is there an easy way to fix this?
I'll try to provide a general answer which might show techniques on how to update one object with another object.
If in the form, you only have the details
as update (update is Partial<Car["details"]>
, you can do this:
const update: Partial<Car["details"]> = this.form.value;
const newCar: Car = {
...oldCar,
details: {
...oldCar.details,
...update
}
Then there's the possibility that the update is (partial) Car
with partial details
:
const update: Partial<Car> & { details: Partial<Car["details"]> } = this.form.value;
const newCar: Car = {
...oldCar,
...update,
details: {
...oldCar.details,
...update.details
}
}
An improbable option is that you have mixed detail and car properties in the update (for whatever reason - you might be doing something wrong). Then you can pick them by hand. Note that this will delete old values if new values are undefined.
const update: Pick<Car, 'name' | 'lastUpdate'> & Pick<Car["details"], 'ownerInfo'> = this.form.value;
const newCar: Car = {
...oldCar,
name: update.name,
lastUpdate: update.lastUpdate,
name: update.name
details: {
...oldCar.details,
ownerInfo: details.ownerInfo
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.