Despite my efforts, I am struggling to refresh the view after retrieving data from an AJAX call in AngularJS

I've been searching for a solution to this problem for quite some time now, but nothing seems to work for me.

Recently, I started delving into Angular and managed to create a basic page with an ng-repeat function that iterates through an object.

My next goal is to update this object by making an AJAX call to an API. However, I'm facing difficulties in achieving this. It appears that the issue lies within the controller function: it's unable to modify an attribute of the same controller.

app.controller('StoreController', [ '$http', 'ajaxFactory',
    function($http, ajaxFactory) {
        this.products = products;
        
        this.getProducts = function() {
            /* This successfully empties the object AND the view upon click */
            this.products = [];
            
            ajaxFactory.getFamily2().then(function(data) {
                /*
                 * Unfortunately, this does NOT work as expected; neither
                 * emptying the object nor the view upon click.
                 */
                /*
                 * I am certain that the AJAX call is functioning correctly,
                 * as I can see the results and even alert its content.
                 */
                this.products = data;
            });
        };
    } ]);

Thank you in advance for your assistance.

FULL CODE: Html:

<div ng-app="catalogo">
<div ng-controller="StoreController as store">
    <header class="text-center">
        <h3>– An Angular Catalogue –</h3>
    </header>

    <div class="container" ng-controller="TotalPriceController as total">
        <div class="row">
            <div class="col col-xs-4"
                ng-repeat="(key, product) in store.products"
                ng-class="{ hero: key%2 === 0 }">
                <div class="row">
                    <product-title></product-title>
                </div>
                <div class="row">
                    <product-gallery></product-gallery>
                </div>
                <div class="row">
                    <product-calculate></product-calculate>
                </div>
                <div class="row">
                    <product-tabs></product-tabs>
                </div>
            </div>
        </div>
        <div class="row">
            <button ng-click="store.getProducts()">Click Here!</button>
            <product-total></product-total>
        </div>
    </div>
</div>

JS:

(function() {
var app = angular.module('catalogo', [ 'store-directives' ]);

app.factory('ajaxFactory', function($http) {
    var factory = {};
    factory.getFamily2 = function() {
        return $http.get("http://apigility-ds.gsanet.it/rpc").then(
                function(result) {
                    return result.data;
                });
    }
    return factory;
});

app.controller('TotalPriceController', function() {
    this.totalPrice = 0;

    this.calculateTotalPrice = function() {
        this.totalPrice = 0;
        for ( var x in products) {
            var product = products[x];
            if (typeof (product.num) !== 'undefined') {
                this.totalPrice += (product.price * product.num);
            }
        }
    };
});

app.config(function($httpProvider) {
    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

app.controller('StoreController', [ '$http', 'ajaxFactory',
        function($http, ajaxFactory) {
            this.products = products;

            this.getProducts = function() {
                this.products = [];

                ajaxFactory.getFamily2().then(function(data) {
                    this.products = data;
                });

            };
        } ]);

app.controller('ReviewController', function() {
    this.review = {};

    this.addReview = function(product) {
        product.reviews.push(this.review);
        this.review = {};
    };
});

var products = [ {
    name : 'Balloons',
    price : 7.99,
    description : "A pack of colorful balloons",
    images : [ "../img/balloons.jpg", "../img/balloons2.jpg" ],
    specs : {
        number : 10,
        color : 'various'
    },
    reviews : []
}, {
    name : 'Cards',
    price : 3.99,
    description : "Beautiful set of cards.",
    images : [ "../img/cards.jpg", "../img/cards2.jpg" ],
    specs : {
        type : 'poker deck',
        cards : 52
    },
    reviews : []
}, {
    name : 'Watch',
    price : 159.99,
    description : "An amazing watch that will make you look cool.",
    images : [ "../img/watchmaker.jpg", "../img/watchmaker2.jpg" ],
    specs : {
        color : 'black',
        year : '2014',
        brand : 'SWATCH'
    },
    reviews : []
} ];

})();

Answer №1

There seems to be an issue with the reference to this.products within a closure. It appears that it is not referring to the this.products declared outside of the getProducts function. One way to correct this is by making the following changes:

app.controller('StoreController', [ '$http', 'ajaxFactory',
    function($http, ajaxFactory) {
        var controller = this;
        controller.products = products;

        controller.getProducts = function() {
            /* This code successfully empties the object and the view on click */
            controller.products = [];

            ajaxFactory.getFamily2().then(function(data) {
                /*
                 * However, this code does not empty the object or the view on click
                 */
                /*
                 * I can confirm that the AJAX call is working as expected since I am able to see the results
                 * and even display its content in an alert
                 */
                controller.products = data;
            });

        };
    } ]);

In addition to this, you may want to explore using Angular services to enhance the robustness of your code and facilitate easier testing.

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

The transition between backgrounds is malfunctioning

I want to create a smooth transition effect for changing the background of an element within a setInterval function. Currently, the background changes immediately, but I would like it to transition over a period of time. var act = true; setInterval(func ...

Is there a way to align two canvases perfectly on top of each other?

My current challenge involves the need to position one HTML5 canvas on top of another. So far, I have successfully accomplished this using the following method: <canvas id="lower" width="900" height="550" style="position: absolute; left: 0; top: 0; z-i ...

Encountering a CORS request error in JHipster 3

Currently, I am in the process of upgrading from JHipster 2 to JHipster 3. Some of my modules are making RESTful requests to retrieve JSON data. Below is the code snippet for JHipster 2 which is working fine: 'use strict'; angular.module(&apos ...

Unable to assign an IP address to an Express JS application

Struggling to test a specific endpoint in Express, but consistently encountering a 404 error. var express = require("express") var app = express() //var http = require('http').Server(app) app.get('/', function(req,res){ res. ...

Determine the presence of a Facebook user by using JavaScript

I am trying to find a method to verify the existence of a Facebook user based on their ID. As far as I understand, there is a Graph API that can provide a Facebook user's profile picture using their ID in this format: I have noticed that if an inval ...

Guide on tallying a unique value of a chosen option within a table using jQuery

I have select elements in my table. I am trying to determine if any of the selected options in those select elements have the value of optional. If any of the select elements has optional selected, then I want to display a text field below it. However, I a ...

NgFor is failing to display data from a fully populated array of objects

CLICK HERE FOR THE IMAGE So, let's tackle the issue at hand. I have an array that contains data fetched from an API. These data points are essentially messages. Now, below is the TypeScript file for a component where I aim to display all these messag ...

Locating a specific item within a mongoDB array

In my collection, I have a mix of strings, objects, and an array containing multiple objects. I'm trying to delete all orders with the object id of ObjectId("587ec66e5ed5cb0061092dbe"). Please refer to the schema and data provided below. I've exh ...

Tips on connecting the endpoints of two parallel quadratic Bezier curves that both begin with a MoveTo command

I am currently working on creating a Sankey Diagram from scratch using VueJS and SVG. I have encountered challenges in closing the paths of two parallel quadratic Bezier curve paths from nodes to nodes. For instance, after some additional calculations, I ...

Ways to implement StackNavigator along with Redux?

Is there anyone who can assist me in integrating StackNavigator and Redux? It seems straightforward, but I'm encountering issues. index.ios.js import React from 'react' import { AppRegistry } from 'react-native' import { Provi ...

Difficulty Sorting Dates in Material UI DataGrid

I have a DataGrid in Material UI, and one of my columns displays dates. Following the guidance from the Material UI documentation, I have set the type to "date" in the column array: { field: "submittedAt", headerName: "Submitted", minWidth: 150, flex: 2, t ...

Sort the array by unique ID and retrieve the object with the first and last index

I am working with an array that looks like this: [{ "res": [ '123', 'One', '20210318' ] }, { "res": [ '123', 'One', '20210319' ] }, { "res": [ '123&ap ...

No overload error encountered with TypeScript function call

I am working on an async function that communicates with the backend and I need it to handle axios error messages. My goal is to display these messages in a form. export async function register( prevState: string | undefined, formData: FormData ) { t ...

What is the default parameter type in react-native?

Currently, I am delving into React-native framework. While browsing through the Facebook ListView sample page, I stumbled upon the below code snippet. _renderRow: function(rowData: string, sectionID: number, rowID: number) { .... Interestingly, I have n ...

Avoiding Socket IO from timing out when the browser page is inactive or not the focused tab on Google Chrome, Mozilla Firefox, and Safari mobile browsers

I have developed a basic chat application using socket io. The functionality is quite similar to the socket io chat official demo. However, I am facing an issue where Socket io times out on all mobile browsers when the user minimizes the page, opens anothe ...

Error: Collection2 validation did not pass: The field 'name' must be filled in, the field 'email' cannot be empty, and the field 'message' is mandatory

I need to set up a way for visitors to send messages through my website const mongoose = require("mongoose"); mongoose.connect("MongoDb-Connection-Uri") .then(() => { console.log("mongodb connected"); }) .catch(() => { console.log("fail ...

Building nested objects within an isolated scope can be achieved by following these steps

I am trying to implement a nested structure on my nested scope within a directive, as shown below: angular.module('myAddress').directive('myAddress', [function () { return { restrict: 'AE', controller: &ap ...

Tips for keeping track of data for various individuals

I am in the process of developing a Dungeons and Dragons discord bot for my friends. I would like to enable the players to use a specific command to input their character information such as first/last name, race, class, and more. I attempted to utilize m ...

Troubleshooting ActiveXobject Errors in JavaScript

I've implemented this script on my Default.aspx page. <script id="clientEventHandlersJS" type="text/javascript"> function Button1_onclick() { var locator = new ActiveXObject ("WbemScripting.SWbemLocator"); var s ...

The function .click() fails to execute upon page load, yet it functions successfully when utilized in the console

This is the code I am using: <script> document.getElementById("test").click(); </script> When I try to trigger the click(); function on page load, it doesn't work. However, when I execute it in the console on Firefox, it works ...