0

I'm working on an AngularJS project using ES6 and Controller As syntax and running into some new issues. I have a ng-repeat which calls a function to update some data. I want the item passed to a function within ng-repeat to be updated when a promise returns. The issue is I can't seem to reference it again after the promise comes back.

<div ng-repeat="item in ctrl.thing.items">
  <div ng-click="updateItem(item)">Update Item</div>
</div>

Then the update function here:

updateItem(item) {
    let i = new this.Item(item);
    i.update().then(function(response) {
        item = response.data; // Item does not get updated in controller
    });
}

I've tried setting item to a variable within the function and various other things I could try to re-reference, but have been unsuccessful.

The only success I've had is passing the index and then referencing the original object by setting a let t = this; before the promise and then t.thing.items[index] = response.data. This works, but feels a bit ugly compared to usually being able to reference objects more directly. What am I missing here?

Ryan
  • 17,511
  • 23
  • 63
  • 88

1 Answers1

0

As you've pointed out, by calling item = you are actually just reassigning the reference to the parameter being passed into updateItem - you're not actually updating the original item object.

To get around this, you could update the properties of item with all of the data from response.data using Object.assign:

updateItem(item) {
    let i = new this.Item(item);
    i.update().then(function(response) {
        Object.assign(item, response.data); // Copy the enumerable properties from response.data into item
    });
}

Note however that won't delete any properties that were previously in item but are no longer in response.data;

CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
  • Can I reassign the reference and have it updated throughout? I just tried Object.assign and it does then update the view with other changes whereas reassignment does not. I feel like previously I have reassigned the object passed in and it has worked how I expected it here to, although I haven't slept in quite a while so I may I'm not thinking clearly. – Ryan May 28 '18 at 11:18
  • Been a while since I used Angular myself, so also might not be thinking clearly, but I'm pretty sure this is the only way to do this unless you're binding the variable to a service, or directly onto the controller, e.g. `$scope.item = ` may have worked, but you would need to pass the scope into `updateItem` too – CodingIntrigue May 28 '18 at 11:20