0

I am new to AngularJS. I cannot seem to get $http to work. I have the following factory:

app.factory('employeeFactory', function ($http) {
    var factory = {};

    // get data form controller
    var employees = [];
    var Url = "../../../Employee/GetEmployees";

    // this does not work ----------------------------
    $http.get(Url, { params: { term: 'Step' }}).
      success(function (response, status, headers, config) {
          employees = response.data
      }).
      error(function (response, status, headers, config) {
          alert(error);
      });

    // this works using JQuery ajax ----------------------------
    $.ajax({
        url: Url,
        data: { term: 'Step' },
        dataType: "json",
        type: "GET",
        error: function (request, status, error) {
            alert(error);
        },
        success: function (response) {
            $.each(response.data, function (i, obj) {
                employees.push({ EmployeeName: obj.EmployeeName, EmployeeNumber: obj.EmployeeNumber });
            });
        }
    });

    factory.getEmployees = function () {
        return employees
    };

    return factory;
});

And the following controller:

app.controller('EmployeeController', function ($scope, employeeFactory) {
    $scope.employees = [];
    init();
    function init() {
        $scope.employees = employeeFactory.getEmployees();
    }
});

The ajax call in the factory works but the $https doesn't (both are in the factory, I just comment out one or the other while testing). I looked in google chrome dev tools and both calls return data in the same format, but the $http data is not being bound to the html:

<div class="container">
    <h4>This is view 1</h4>
    Type a name to filter: <input type="text" data-ng-model="employeeSearch" />
    <ul>
        <li data-ng-repeat="employee in employees | filter:employeeSearch | orderBy:'EmployeeName'">{{ employee.EmployeeName  }} - {{ employee.EmployeeNumber }}</li>
    </ul>
</div>

Here is the format the factory returns for both calls:

{data: [{EmployeeNumber:123456, EmployeeName:Johnson,Bob},…]
data: [{EmployeeNumber:123456, EmployeeName:Johnson,Bob},…]
    0: {EmployeeNumber:123456, EmployeeName:Johnson,Bob}
        EmployeeName: "Johnson,Bob"
        EmployeeNumber: "123456"

I don't understand why, when both calls return the data to the view in the same format, the binding is not occurring with the $http method. Any help is appreciated

1
  • Can you guarantee the AJAX call has been completed before you getEmployees? I'm not sure why that would be different between the two, but as far as I can see there's nothing in your employees class that would guarantee the data has been read first. Commented Oct 29, 2014 at 13:41

2 Answers 2

4

The jQuery ajax works because you push to the returned reference.
In the angular ajax success handler you overwrite the variable, but the return value is still the empty reference.

So to get the angular $http function working, you should do the following in your success handler:

angular.forEach(response.data, function(value) {
    employees.push(value);
});
Sign up to request clarification or add additional context in comments.

4 Comments

That was it! should I have to push the data? I don't see a lot of examples that use push out there, so I am wondering if I am going about this wrong. The push in the ajax call was only there because that is the example I found. Btw, thanks a ton
@friedi I think is correct. Its a reference issue, you're retrieving the empty array before it can be assigned. While this forEach loop would correct that I don't think this is the best way. You need to refactor your service to take advantage of the promise returned by the $http call. You should return the promise and then return the data within the success call.
Yeah, it's not the best way and I would do it the way @m.e.conroy suggested
I will have tolook into m.e.conroy's recommendation. Thanks again, both of you.
0

use this code:

service:

app.factory('employeeFactory', function ($http) {
    var employees = [];
    var Url = "../../../Employee/GetEmployees";
    var factory = {
     getEmp:function(){
         return $http.get(Url, { params: { term: 'Step' }})
     }
    }
    return factory;
});

controller:

app.controller('EmployeeController', function ($scope, employeeFactory) {
    $scope.employees = [];

    function init() {
        employeeFactory.getEmp().then(function(data){
         $scope.employees=data;
        })
        .catch(function(err){
         console.log(err);
        })
    }
  init();
});

2 Comments

This is better but you could do the success and error chained functions in the service rather than controller. The controller shouldn't have to know that its a promise only that it wants the data.
I tried this but it returns a ul with four (4) li and a dash following each, but no data

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.