"Step-by-step guide on associating JSON data with <li> elements using AngularJS

Currently, I am working on creating an application using AngularJS that involves retrieving data from a database and populating a list item with that data.

To achieve this, I have written a WebMethod as shown below:

[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);


    }

This method returns the data in JSON format.

I am using the following JavaScript code to bind the data:

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();
});

In my view, the HTML code looks like this:

<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>

However, despite my efforts, it is not functioning as expected. It works fine when I hard code the data in the factory, but when I try to fetch the data using an AJAX call, it fails. I am struggling to understand why this issue is occurring.

Answer №1

What's causing the issue?

  • Attaching a variable to the scope is problematic when its value is dependent on an asynchronous call.
  • When utilizing third-party libraries that alter the scope, it is necessary to explicitly invoke $scope.$apply().

Opt for $http over $.ajax and embrace 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){
      // handle errors
    });
});

If you still prefer using $.ajax

  • Make sure to manually trigger $scope.$apply() after receiving the response.
  • Employ promises or callbacks to bind data to scope variables.

If you intend to retrieve data from the server before loading the view

  • @Misko Hevery provides valuable insights: Delaying AngularJS route change until model loaded to prevent flicker

Although unrelated to your current issue, ensure jQuery is loaded before 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> 

Answer №2

Your issue lies with the JavaScript function "SimpleFactory.getCustomer()" returning before the AJAX call is completed.

It is recommended to use $http in Angular instead of jQuery's ajax for several reasons:

  • $http returns a promise, making it consistent with other areas in Angular and allowing for the use of .success and .done methods that align with Angular conventions.
  • $http automatically sets the content type to 'application/json' for POST requests.
  • The success and error callbacks of $http will execute within the Angular context, eliminating the need to manually trigger a digest cycle - if using jQuery, you may need to call $apply.

You can implement this as shown below:

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;
    });    
}]);

Answer №3

Factories in AngularJS operate as singletons, meaning that the code you've written will trigger the ajax call when the factory is injected into the controller. This explains why you're not seeing the customer data right away, as the server response is processed after the json data is assigned to the scope variable.

A quick (albeit temporary) solution is to encapsulate 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 more efficient approach would be to utilize either the built-in $http or the $resource angular service. The latter requires using RESTful services (recommended). If you still prefer to use jQuery ajax calls for some reason, you'll need a way to notify Angular when the ajax call is complete: consider exploring the $q promise service.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the reason that jQuery does not work on HTML generated by JavaScript?

One of my JavaScript functions, named getImages, is responsible for loading the following HTML structure: // Function starts here function getImages() { $.getJSON(GETIMAGELIST, function(data) { var items = []; // Populating the HTML $.each(dat ...

Utilizing Ionic Storage to set default request headers through an HTTP interceptor in an Angular 5 and Ionic 3 application

I'm attempting to assign a token value to all request headers using the new angular 5 HTTP client. Take a look at my code snippet: import {Injectable} from '@angular/core'; import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from ...

"Mastering the art of combining HTML, JSON, and AJAX for seamless

I'm having some trouble figuring out how to pass the HTML element and PHP variables when using JSON Encode function and Ajax to display output from the database. I want the data to be shown through a JSON and ajax request. Any help would be appreciate ...

Looking to arrange an object by the value of a nested object in Typescript/Angular?

I'm currently developing an Angular 9 application focused on covid-19 cases, and I need to arrange my objects by the value of nested objects. Here is the dataset that I want to organize alphabetically based on the 'state' field values: stat ...

Displaying dropdown options based on the previous selection made by the user

Can I link the data in my second dropdown to the selection made in the first dropdown? I tried a similar solution from stackoverflow without success. You can find the reference here. The code works when directly copied and pasted but not within my system. ...

Extract the string from a JSON document containing nested JSON objects and arrays, each with multiple JSON entities

Can someone guide me on how to properly format and display JSON data as shown below? Thank you! {"IsValid":true,"Values":{"editions":[]},"error":null} ...

Can you help me figure out where I went wrong with my JSON Post?

My current task involves populating a model with data retrieved from a Restful API. I am handling the deserialization of JSON in the following manner within my code: func DoLogin(_ user:String, _ psw:String) { let url = URL(string: "http://162.209.99. ...

The function "useLocation" can only be utilized within the scope of a <RouterProvider> in react-router. An Uncaught Error is thrown when trying to use useLocation() outside of a <Router>

When attempting to utilize the useLocation hook in my component, I encountered an error: import React, { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import { connect } from 'react-redux'; import { ...

What is the best way to ensure that a directive stays up to date with any changes made to the collection

After sending a directive a collection, I noticed that when I update the collection in the parent scope, the directive fails to update accordingly: http://jsfiddle.net/edwardtanguay/kj4oj1aa/9/ <div ng-controller="mainController"> <div item- ...

Converting JSON objects to JSON arrays in Spark using Scala

I have a schema that is structured as follows: root |-- FirstName: string (nullable = true) |-- Age: integer (nullable = true) I am interested in modifying this schema and saving the data into a file so it appears like this: ["Alice", 22], [&q ...

Error encountered: Unable to render template at an unidentified path in a NODE JS environment

I am currently working on a HTML page with the help of node js. This is the code I have written for running app.js: app.get('/',function(req,res)){ res.render('index',{"data":["name" , "ABC"] }); }); In order to display the na ...

Showing a series of text entries one after the other, each appearing with a smooth fade-in and fade-out

I am eager to showcase a list of text in a sequential order, implementing a fade-in/fade-out effect and concluding with the display of an image. Additionally, I aim to have all the text centered on the page. <div>a<div> <div>b</div> ...

Connecting data with Ember CLI and ASP.NET WebAPI

I am facing an issue with integrating my Ember Cli project running on localhost:4200 and my asp.net webapi project running on localhost:56967. Both projects function properly individually: I can run my Ember app, test various routes, and access my api succ ...

JavaScript innerHTML not functioning properly when receiving a response from a servlet

Can someone help me troubleshoot the code below? I'm receiving a response from the servlet, but I can't seem to display it inside the div. Here is the response: lukas requests to be your friend &nbsp <button value="lukas"onclick="accfr(th ...

I am looking to dynamically alter the CSS background URL using JavaScript

Currently, I am looking to update the background image url using JavaScript. Most tutorials I've come across involve having the image downloaded on the desktop and then providing its path. However, in my scenario, the user will input an image link whi ...

Implementing a button callback function using Aurelia binding

Is there a way to pass an array of custom button objects to a specific element? Here's an example: <my-component header="My Title" buttons.bind="[{icon: 'fa-plus', display: 'New', action: onNew}]"> </my-component> ...

Can you explain the purpose of the .json() function in Angular2?

Can you explain the purpose of the .json() function within http requests in Angular2? Here is an example code snippet: this.http.get('http://localhost:8080/getName') .subscribe(res => this.names = res.json()); Is it correct to assume that t ...

Creating a nested JSON response with an Array in a Stored Procedure

I have extracted a dataset from a stored procedure result +------+--------+---------------------+------------+ | Line |Status | Consent | tid | +------+--------+---------------------+------------+ | 1001 | 1 | Yes | ...

What is the process of transforming a tree into a JSON object?

I have a tree structure that I need to convert into JSON format for use with a jquery option tree. NodeId, Title, Level 1, cars, 0 2, boats, 0 3, oldtimer, 1 4, trucks, 1 5, heavytrucks, 4 The desired tree structure is as follows: boats cars - oldtimer - ...

MOSQL: JSON ARRAY data type returning SQL literal resulted in a Sequel::Error

After extensive testing, I encountered an issue with the tool used to migrate data from mongo db. Despite searching for a solution at length, no clear answer has emerged yet. Please see the stack trace below. mosql version unknown (however, upon attemptin ...