Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Issues with references when using services and ng-repeat

Tags:

angularjs

Im finding myself fighting with 'pointers' in javascript. It's like I'm in C++ again. I would like to know your approach to the following issue Im having.

My case: I have a ng-repeat that goes over a collection. When clicking one of the collection elements, I do a copy of the element, do changes over it and POST/PUT data to server.

If the server replies 200 then I will apply those changes to the collection. The collection contains objects, so it means that Im working with references NOT values.

The module definition with a service:

angular.module('dataModule', [])

    .service('DataService', function () {
        this.collection = [{id:0, who: 'I'},
                           {id:1, who: 'YOU'}, 
                           {id:2, who: 'HE'},
                           {id:3, who: 'SHE'},
                           {id:4, who: 'IT'}];
})

And here the controller:

.controller('listCtrl', function ($scope, $timeout, DataService) {
    // Data used in view
    $scope.collection = DataService.collection;

    // Action trigger from the view
    $scope.change = function(data, index){
        // Get a copy 
        var copy = angular.copy(data);

        // Apply changes over the copy
        copy.id = data.id*100*index;

        // Simulate POSTing/Updating data to server
        console.log('Sending data to server...');
        $timeout(function(){
            // Response is 200
            var response = 200;

            // Assigning copy -> data
            data = copy;

            // The prev. assignment is not updating the collection
            // Of course I could do $scope.collection[index] = copy; 
            //  because this case is simple enough.
            // Im finding myself having the service with methods find, edit, ...
            // What's a better approach?

        }, 2000)
    }
});

As I said in the comments, Im finding myself implementing functions like find, edit or get in the service. Is that the approach to go???

Here is the jsfiddle http://jsfiddle.net/kitimenpolku/M66LV/5/ in case I was not able to explain it correctly.

like image 248
kitimenpolku Avatar asked May 31 '26 23:05

kitimenpolku


2 Answers

From my perspective, there are two ways you can go with updating the view after you write to the server:

  1. You ask the server for the entire collection again, and then set it locally. This requires the use of promises and replacing the current collection with a new one. This replacement will automatically trigger an update in the ng-repeat directive you are using in your template.
  2. You perform the same transformation locally, as you mentioned yourself. This entails finding the correct index of the array and swapping out the old object for the edited one. This is how I like to setup my own applications and it's really not so hard to do. Here's how:

I can see that you really are thinking of this javascript replacement as if it were in c++. Here, you are correct in that data = copy; in your server callback is merely updating a reference, not any data itself.

Instead, you can alter the collection itself directly: $scope.collection[index] = copy

Here's a working fiddle: http://jsfiddle.net/wilsonjonash/GZ2eR/

like image 69
Jonathan Wilson Avatar answered Jun 02 '26 14:06

Jonathan Wilson


data is a reference to the original item but using data = copy is just invalidating data so the original never gets updated.

So to update the original item you need to perform.

 data.id = copy.id;
 data.who = copy.who;

or

$scopy.collection[index] = copy

fiddle with updated code

http://jsfiddle.net/M66LV/7/

like image 44
Dreamwalker Avatar answered Jun 02 '26 12:06

Dreamwalker