What is the difference between function () {} and () = {}? Why does not $ http.get work?

9

When I use

 $http.get('/products').then((response) => {
   this.products = response.data;
   this.allProducts = response.data;
 });

The page loads with the products in Google Chrome, but when I use

$http.get('/products').then(function(response) {
  this.products = response.data;
  this.allProducts = response.data;
});

Products are not loaded: (

Because of Safari and Safari Mobile, I am not able to use the syntax () = > of ES2015. The browser gives a "compilation" error.

Does anyone know what I need to do to use function(response) {} and get the products?

Thank you

    
asked by anonymous 29.07.2016 / 16:36

3 answers

15

As I noticed you did not explain the difference between () => {} to function() {} , then although there is a correct answer, I'll explain this difference.

First of all, it is very common to think that both codes are equivalent, since ES6 has several syntax sugar to make code more readable and concise, arrow functions are usually confused with functions ES5 %. But going straight to the point there are five differences between the two codes:

Context

Arrow functions have this léxico while the normal model has this dinâmico . This means that arrow functions inherits the local context from which it was declared, while the normal template has the context associated with the object it is linked to at the time of the call (if it is not associated with anyone in the call, it automatically% as the global context, which in the case of browsers is this )

var normal = function() {
  return this === obj;
};

var arrow = () => {
  return this === window;
};

var obj = { normal: normal, arrow: arrow };

obj.normal(); // true
obj.arrow(); // true

normal(); // false

Builder

window can not be Arrow functions , so it is not possible to use the constructors operator with it.

var Normal = function() {};
var Arrow = () => {};

new Normal(); // Normal {}
new Arrow(); // Arrow is not a constructor

Arguments

new does not have the array-like object Arrow functions .

var noop = () => {
  return arguments;
}

noop(); // ReferenceError: arguments is not defined

Function name

Function expressions can be named explicitly, this is useful in some scenarios involving recursion, and in case of exception it is easier to trace the code, since the function name is used in the exception stack shown to the developer. Only arguments can not be named explicitly, they end up inheriting the name of the variable where it was created.

var fn = function nome() {};
fn.name; // nome

var fn = () => {};
fn.name; // fn

Return

Function expressions need to explicitly declare what the function return will be, while Arrows Functions allow writing in a shortened model where the last parsed expression will be the return of the function when the Arrow Functions keys are omitted.

var fn = function() { return 1; }; // retorna 1

var fn = () => 1; // retorna 1
var fn = () => (1, 2, 3); // retorna 3, última expressão avaliada

var fn = () => { 1 }; // retorna undefined
var fn = () => { return 1 }; // retorna 1

What would be an equivalent model of {} then?

Ignoring the fact that () => {} can not be used as arrow functions and do not receive constructors , the most equivalent model between arguments and traditional functions would be this:

// modelo nomeado
var name = (() => { /* code */ })
var name = (function name() { /* code */ }).bind(this)

// modelo anônimo
(() => { /* code */ })
(function() { /* code */ }).bind(this)

In this case the arrow functions can be exactly the same between the two models and they will work exactly the same. Of course, there are other ways to simulate the behavior of code . One is to store the arrow functions context in a variable and use that variable in the traditional function instead of its own this , which the other responses showed.     

02.08.2016 / 13:20
6

I may be wrong, but I read an article by AngularJs (I am not finding the reference now) that addressed this issue in specific when combined with the syntax as method, where it is common to use this within controller .

The big problem in this is to know which scope this is assigned, because in order to pass the data to the view, it must be in the scope of controller .

That's where I believe your error is, because this is in the scope of $http

.controller('myCtrl', function($scope, $http) {
    this.products = []; //Aqui ele está no escopo do controller - Irá passar para view

    $http.get('minha/url/aqui').then(function(response){
        this.products = response.data; //Aqui ele está no escopo do $http - Não irá passar para view
    })
})
What is usually done, to make sure you always use the scope of controller when assigned to this , is to create a variable at the beginning of controller and use it, instead of using this . So:

.controller('myCtrl', function($scope, $http) {
    var vm = this; //Pode ser vm (ViewModel) ou outra variável de sua preferência

    vm.products = []; //Aqui ele está no escopo do controller - Irá passar para view

    $http.get('minha/url/aqui').then(function(response){
        vm.products = response.data; //Está apenas atualizando o products definido anteriormente
    })
})
    
29.07.2016 / 16:54
0

I do this and it works:

angular.module('myApp', []);

angular.module('myApp')
.controller('myCtrl', function($scope, $http) {

    $scope.content = [];

    $http.get("/content")
    .then(function(response) {
        $scope.content = response.data;
    });

});

Retired and based on: Angular HTTP W3Schools

    
29.07.2016 / 16:43