Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to use angular.copy in my factory?

I'm trying to have the Thing factory make an HTTP request and be able to use the response in my controller.

  1. In my factory I have to do angular.copy(data, arr). Simply doing arr = data doesn't work. Why is this? angular.copy() just a) deletes everything from arr and b) iterates through data and assigns stuff to arr. The only difference between that and arr = data is that arr points to data rather than a new copy of data. Why would this matter? And why doesn't arr = data.slice(0) work (from what I understand, it's pretty much the same as angular.copy)?

  2. What is the best way to accomplish my goal? (use the factory properly)

main.html

<div class="container">

<div class="page-header">
  <h1>Test App</h1>
</div>

<ul>
  <li ng-repeat="thing in things">{{thing.name}}</li>
</ul>

</div>

main.controller.js

'use strict';

angular.module('testApp')
  .factory('Thing', function($http) {
    var arr = [];
    return {
      things: arr,
      get: function() {
        $http.get('/api/things').success(function(data) {
          angular.copy(data, arr); // this works
          // arr = data; but this doesn't
          // arr = data.slice(0); and neither does this

        });
      }
    };
  })
  .controller('MainCtrl', function ($scope, Thing) {
    Thing.get();
    $scope.things = Thing.things;
  });
like image 429
Adam Zerner Avatar asked Feb 07 '15 05:02

Adam Zerner


People also ask

What is the use of Angular copy?

angular. copy() is used when we want to retain the value of an object which we are copying to another variable.

What's alternative to Angular copy in Angular?

The alternative for deep copying objects having nested objects inside is by using lodash's cloneDeep method. For Angular, you can do it like this: Install lodash with yarn add lodash or npm install lodash .

Is Angular copy a deep copy?

Explanation : = represents a reference whereas angular. copy() creates a new object as a deep copy.

What is Angular module factory?

What is Factory in AngularJS? Factory is an angular function which is used to return the values. A value on demand is created by the factory, whenever a service or controller needs it. Once the value is created, it is reused for all services and controllers. We can use the factory to create a service.


1 Answers

Your problem is not related to angular, but to Javascript.

var arr = [] // arr is a pointer to an empty array
var things = arr  // things is a pointer to the same empty array
arr = data   // now arr points to data, but things still points to the empty array

You can convince yourself of that by running the following code:

var a = [1];
var b = a;
a = [2];
// Now if you console.log a and b, a === [2] and b === [1]

However if you manipulate the property of an object

var a = { data: 1 }
var b = a;
a.data = 2;
// Now a.data and b.data are the same: 2
a = { data: 3 };
// Here we changed a, not its property, so a and b are not the same anymore
// a.data === 3 but b.data === 2

If you understand that, there are many ways to solve your issue, such as:

angular.module('testApp')
  .factory('Thing', function($http) {
  var obj = {};
  return {
    things: obj,
    get: function() {
      $http.get('/api/things').success(function(data) {
        obj.data = data;
      });
    }
  };
})

And in your HTML use things.data.

Or if you don't want to use an object property, but directly the array, instead of replacing the pointer you need to only update the content of the array (so arr still points to that same array):

angular.module('testApp')
  .factory('Thing', function($http) {
  var arr= [];
  return {
    things: arr,
    get: function() {
      $http.get('/api/things').success(function(data) {
        for (var i in data) {
          arr[i] = data[i];
        }
      });
    }
  };
})
like image 146
floribon Avatar answered Sep 17 '22 06:09

floribon