Reputation: 32400
I'm working on an AngularJS application that contains a component that displays data that is fetched from a remote data source, a very common scenario.
Let's call it the "record" component.
The view model for the record looks like this:
record.viewModel = {
firstName: "Bob",
lastName: "Smith",
data1: "foo",
data2: "bar",
dateRange: {
start: "1/1/2019",
end: "12/31/2019"
}
}
I also have "date range picker" component. It uses an AngularJS "<" binding to bind to record.viewModel.dataRange
.
When creating a new record, it is easy to bind a new object to the date range picker component. Just create a new object {}
and assign it to record.viewModel.dateRange
in the $onInit
method. Easy!
However, for updating an existing record, it's much more complicated because the record to be updated is fetched asynchronously. I can't simply assign the fetched dateRange to record.viewModel.dateRange
because that would change the variable's object reference while leaving the binding for the dateRangeObject still bound to the old object reference. The solution I used was to bind a function to the date range picker component and pass the new dateRange to that function.
The solution works, but it's very unwieldy. It's difficult to make code changes without breaking things, and now, I've had to create a new component where the bindings are several layers deep and it's giving me a headache just thinking about it. I don't want to even try to rig up example code because it's so ugly.
I need a better way to do this. I feel like the crux of the matter is the object reference that is bound to the date range picker component.
Can I make it so that if I fetch my view model from an asynchronous data source, I can assign the result to a variable and update the view model for the record component and the date range picker component in fell swoop?
Upvotes: 1
Views: 155
Reputation: 48968
I can't simply assign the fetched
dateRange
torecord.viewModel.dateRange
because that would change the variable's object reference
record.viewModel = {
firstName: "Bob",
lastName: "Smith",
data1: "foo",
data2: "bar",
dateRange: {
start: "1/1/2019",
end: "12/31/2019"
}
}
To update the properties of an object without changing the object reference, use Object.assign
Object.assign(record.viewModel.dateRange, response.data.dateRange);
The Object.assign()
method is used to copy the values of all enumerable own properties from one or more source objects to a target object.
if there are components within components, I have to go thru this and recursively run
Object.assign
To do a deep copy, use angular.copy:
angular.copy(record.viewModel, response.data.viewModel);
Creates a deep copy of source, which should be an object or an array.
Upvotes: 1