Question

am try to develop an application using angular js in which i take take data from database and populate li using that data

for that i write a WebMethod as fallow

[WebMethod]
    public static string getname()
    {
        SqlHelper sql = new SqlHelper();

        DataTable dt = sql.ExecuteSelectCommand("select cust_F_name,Cust_L_Name from customer");

        Dictionary<string, object> dict = new Dictionary<string, object>();
        object[] arr = new object[dt.Rows.Count];

        for (int i = 0; i <= dt.Rows.Count - 1; i++)
        {
            arr[i] = dt.Rows[i].ItemArray;
        }
        dict.Add(dt.TableName, arr);
        JavaScriptSerializer json = new JavaScriptSerializer();
        return json.Serialize(dict);


    }

which return data in json form

am use the fallowing js to bind

var DemoApp = angular.module('DemoApp', []);

DemoApp.factory('SimpleFactory', function () {
    var factory = {};
    var customer;
    $.ajax({
        type: "POST",
        url: "Home.aspx/getname",

        data: JSON.stringify({ name: "" }),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        async: true,
        success: function (data, status) {
            customer = $.parseJSON(data.d);

        },
        failure: function (data) {
            alert(data.d);
        },
        error: function (data) {
            alert(data.d);
        }
    });


    factory.getCustomer = function () {
        return customer;
    };
    return factory;
});

DemoApp.controller('SimpleController', function ($scope, SimpleFactory) {
    $scope.Customer = SimpleFactory.getCustomer();
});

and my view is as fallow

<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="DemoApp">
<head runat="server">
    <title></title>
</head>
<body data-ng-controller="SimpleController">
    <form id="form1" runat="server">
    <div>
        Name<input type="text" data-ng-model="Name" />{{ Name }}
        <ul>
            <li data-ng-repeat="customer in Customer | filter:Name">{{ customer.cust_F_name }} -
                {{ customer.cust_L_name }}</li>
        </ul>
    </div>
    </form>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script src="Script/Home.js" type="text/javascript"></script>
</body>
</html>

but it not working it will work fine if i hard code the data in factory but when i bring data using ajax call it will not work am unable to understand why it so.

Was it helpful?

Solution

Why it's not working?

  • you cannot just attach a variable to the scope when it's value is waiting for on asynchronous call.
  • when you use 3rd-party libraries that changes the scope you must call $scope.$apply() explicitly

prefer $http over $.ajax and use promises!

DemoApp.factory('SimpleFactory', function ($http) {
  return {
    getCustomer: function(){          
      return $http.post('Home.aspx/getname',{ name: "" });
    })
  }
}

DemoApp.controller('SimpleController', function ($scope, SimpleFactory) {
    SimpleFactory.getCustomer().then(function(customer){
      $scope.Customer = customer;
    },function(error){
      // error handling
    });
});

If you still want to use $.ajax

  • you must explicitly call $scope.$apply() after the response
  • you must use promises or callbacks to bind to scope variables.

If you want to first fetch data from the server and than load the view

It's not related to your problem but load jquery before you load angular.js

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script> 

OTHER TIPS

Your problem is the js (the function "SimpleFactory.getCustomer()") is returning before AJAX call returning..

Also, you should use $http in Angular instead of jquery's ajax, because:

  • $http returns a "promise" similar to other areas in angular, which means .success, .done are consistent with angular.
  • $http set the content type to 'application/json' for you on POST requests.
  • $http success and error callbacks will execute inside of angular context so you don't need to manually trigger a digest cycle - if you use jQuery, then it might be necessary to call $apply..

Like this:

var DemoApp = angular.module('DemoApp', []);

DemoApp.factory('SimpleFactory', ['$http', function ($http) {
    var factory = {};

    factory.getCustomer = function () {
        var promise = $http.post('Home.aspx/getname', {name: ''});
        promise.catch(function(error) {
            alert(error);
        });            

        return promise;
    };

    return factory;
}]);

DemoApp.controller('SimpleController', ['$scope', 'SimpleFactory', function ($scope, SimpleFactory) {
    SimpleFactory.getCustomer().then(function(customer) {
        $scope.Customer = customer;
    });    
}]);

Factories in AngularJS are singletons. So the way you've written the code will execute the ajax call when the factory is injected into the controller. You don't see the customer data because the server response will be handled after you assign the json data to the scope variable.

A quick (and dirty) fix which will probably work is wrapping the customer object:

DemoApp.factory('SimpleFactory', function ($rootScope) {
  // ...
  var customer = {};
  // ...

  $.ajax({ 
    // ...
    success: function(data) {
      $rootScope.$apply(function() {
        customer.data = data;
      });
    }
    // ...
  });
});

// In view

<li data-ng-repeat="customer in Customer.data"> <!-- ... --> </li> 

A better approach would be to use either to use the builtin $http or the $resource angular service. The last one requires you to make use of RESTful services (recommended). If for any reason you still want to make use of jQuery ajax calls you need some form of telling Angular that the ajax call has been completed: have a look at the $q promise service.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top