The Angular 1.x Ajax request is not triggering the expected update in the view

I am encountering an issue with my Angular application where the data retrieved from a JSON file is not updating in the view when the JSON file is updated. It seems like the JSON file and the view are out of sync.

As a newcomer to Angular, I am struggling to understand why this is happening and how to resolve it. Below is the script I am currently using:

var todoApp = angular.module("todoApp", []);
var model = {
    user: "Adam"
};
todoApp.run(function($http) {
    $http.get("todo.json").then(function(response) {
        model.items = response.data;

    });
});
todoApp.filter("checkedItems", function(){
  return function(items, showComplete){
    var resultArr = [];
    angular.forEach(items, function(item){
      if(item.done==false || showComplete==true){
        resultArr.push(item);
      }
    });
    return resultArr;
   }
});
todoApp.controller("Todoctrl", function($scope){
   $scope.todo = model;

   $scope.incompleteCount = function(){
     var count=0;
     angular.forEach($scope.todo.items, function(item){
       if(!item.done) {count++}
     });
     return count;
   }

   $scope.warningClass = function(){
     return ($scope.incompleteCount()<3 ? "label-success" : "label-warning");
   }

  $scope.newTodo = function(actionText){
    $scope.todo.items.push({action:actionText, done:false });
  }
});

Content of todo.json file:

[
    { "action": "Buy Flowers", "done": false },
    { "action": "Get Shoes", "done": false },
    { "action": "Collect Tickets", "done": true },
    { "action": "Study Geology", "done": false }
]

HTML code snippet:

<body ng-controller="Todoctrl">
<div class="page-header">
  <h1>{{ todo.user }}'s To Do List
    <span class="label label-default" ng-class="warningClass()"
      ng-hide="incompleteCount() == 0">
      {{incompleteCount()}}
    </span>
  </h1>
</div>
<div class="panel">
  <div class="input-group">
    <input class="form-control" ng-model="actionText">
    <span class="input-group-btn">
      <button class="btn btn-default" ng-click="newTodo(actionText)">Add</button>
    </span>
  </div>
  <table class="table table-striped">
    <thead>
      <tr>
        <th>Description</th>
        <th>Done</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="item in todo.items | checkedItems:showComplete | orderBy: 'action'">
        <td>{{item.action}}</td>
        <td><input type="checkbox" ng-model="item.done"></td>
      </tr>
    </tbody>
  </table>
  <div class="checkbox-inline">
    <label><input type="checkbox" ng-model="showComplete"> Show Complete</label>
  </div>
</div>

Answer №1

It seems like you may need to make some adjustments.

Firstly: Instead of manually handling your $http call, consider using a service for this task.

angular.module('taskManager')
.service('APIService', function($http){

    this.fetchData = function(){
        $http.get("tasks.json")
        .then(function(response) {
             return response.data;
        });

    }
});

This approach allows you to easily refresh your data by simply calling fetchData() again when new JSON is available.

Secondly: I noticed that you are setting the model object inside a run block and accessing it in the controller. This is not recommended.
Consider creating a separate service to handle this initialization process, ensuring it remains active throughout without affecting global variables or $rootScope.

angular.module('taskManager')
.service('TaskService', function(APIService){
    this.model = {
        user: "Emily",
        tasks: []
    };

    // logic to fetch tasks; can be encapsulated within a function
    APIService.fetchData()
    .then(function(tasks){
        this.model.tasks = tasks;
    }) 
});

Thirdly: Utilize the service created earlier in your controller to populate the tasks object. Whenever there's an update in the JSON data, trigger an event to ensure synchronization between the service and controller.

// within your controller
$scope.tasks = TaskService.model;

Answer №2

When working with Angular, we typically utilize the $scope variable to connect view elements to controller values. However, it's important to note that this $scope is not accessible in the run phase. Instead, we rely on the $rootScope.

The $rootScope is a scope that is attached to the HTML element containing the ng-app directive.

This $rootScope persists throughout the entire application.

var app = angular.module("app", []);
app.run(function($http, $rootScope) {
    $rootScope.data = {
        user: "John",
        items: []
    };
    $http.get("data.json").then(function(response) {
        $rootScope.data.items = response.data;
    });
});

Answer №3

Initially, it is advisable to move your Http.get function from the run section to the Todoctrl controller. This way, you can utilize $rootScope to transmit the data to other parts of the code as its current placement makes it challenging to determine if it functions correctly.

Additionally, if the get request is successful but does not update accordingly, consider implementing the solution provided in this resource:

Furthermore, make use of Chrome developer tools to effectively debug your code line by line for better troubleshooting.

Answer №4

$scope cannot be utilized within the .run() function in AngularJS.

var taskApp = angular.module("taskApp", []);
var userData = {
    user: "Eve"
};
taskApp.run(function ($http, $rootScope) {
    $http.get("tasks.json").then(function (response) {
        userData.items = response.data;
        $rootScope.userData = userData; // Access userData in HTML page
    });
});

taskApp.controller("TaskCtrl", function ($scope) {
    $scope.task = {};
    $scope.$watch('userData', function () {
        $scope.task = $rootScope.userData;
    });

    $scope.incompleteCount = function () {
        var count = 0;
        angular.forEach($scope.task.items, function (item) {
            if (!item.done) {
                count++
            }
        });
        return count;
    }

    $scope.warningClass = function () {
        return ($scope.incompleteCount() < 3 ? "label-success" : "label-warning");
    }

    $scope.newTask = function (actionText) {
        $scope.task.items.push({
            action: actionText,
            done: false
        });
    }
});

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

Optimize Material-UI input fields to occupy the entire toolbar

I'm having trouble getting the material-ui app bar example to work as I want. I've created a CodeSandbox example based on the Material-UI website. My Goal: My goal is to make the search field expand fully to the right side of the app bar, regar ...

Global Day "Sequence" Initiates Subtraction Instead of Preserving Its Authentic Structure

While using Python's Selenium, I am facing a challenge when trying to "inject" an international date string in the specified format into a web page. Unfortunately, instead of getting the expected string, I am getting a result that seems like subtracti ...

Conquering challenges arising from organizing subdirectories for js/css/xml files

During the process of developing a website with html, css, js and xml files stored on my computer (not yet online), I initially kept all the files in one folder along with an images folder. However, as the project progressed and things started to get mes ...

Can Angular input[number] fields be left empty?

Is there a simple method to allow the input[number] directive to accept an empty value? I am looking for an input that can take values from 1 to 100, but also be able to remain blank. I hope there is an uncomplicated way to achieve this without having to ...

Python: Storing data retrieved from AJAX response as a .json file and loading it into a pandas DataFrame

Greetings and thank you for taking the time to read this, My objective is to extract company information from a specific stock exchange and then store it in a pandas DataFrame. Each company has its own webpage identified by unique "KodeEmiten" endings, wh ...

Tips for updating the value of an input text field in one HTML table according to a certain value entered in a different input text field located in another HTML table

I am working with an HTML table that consists of one row. Within this row, there are two TDs which each hold their own tables (each containing 10 rows with 10 input fields). My goal is to update the value of another corresponding text field based on change ...

Enhance the annotation of JS types for arguments with default values

Currently, I am working within a code base that predominantly uses JS files, rather than TS. However, I have decided to incorporate tsc for type validation. In TypeScript, one method of inferring types for arguments is based on default values. For example ...

Methods like jQuery blink(), strike(), and bold() offer dynamic ways to manipulate

I'm currently tackling an inquiry. The code I crafted seems to be functioning without any issues: (function () { if($('#target:contains("bold")')) { $('#target span:first').css('font-weight','bold ...

"Exploring the possibilities of integrating Typescript into Material-UI themes: A step-by

I'm experiencing some issues with Typescript pointing out missing properties in the palette section. Although adding //@ts-ignore resolves the problem temporarily, I would prefer to find a cleaner solution. As a newbie to Typescript, here is my attemp ...

Is there a way to transfer the data from a chosen row into a different table?

My task involves using a table with two different conditions. In the first table, I display all incoming data. Then, in the second table (referred to as "select summary"), I want to show the row selected in the first table. To achieve this, I am utilizing ...

Building a Dynamic Search Feature with jQuery, C#, and SQL Server Integration

Trying to implement jQuery autocomplete on dynamically generated textboxes for the first time. ASMX page code is generating results as expected, but facing issues with JavaScript autocomplete functionality. Even after debugging, the script does not call th ...

Toggle the visibility of a div based on the id found in JSON data

I am looking to implement a JavaScript snippet in my code that will show or hide a div based on the category ID returned by my JSON data. <div id="community-members-member-content-categories-container"> <div class="commun ...

including identical item in the array

<!DOCTYPE html> <html> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css"> <body> <script> var app = angul ...

Error message appears when attempting to submit a form with empty values in NodeJs

I need help troubleshooting a display error that occurs when setting empty values in form fields. When I delete the row with res.redirect('/') and then attempt to register, if I refresh the page later, an error appears. However, if I keep this re ...

Creating a method in Angular that combines async/await functionality with Observables

After transitioning from using async/await to Observables in Angular, I am trying to refactor the following code snippet to make it work with Observables: async refreshToken() { const headers = this.authStorage.getRequestHeader(); const body = { ...

What is preventing me from executing node.js and socket.io within a screen or utilizing Forever?

I'm encountering an issue with running nodejs in a screen. The problem arises when I leave the screen and no sockets are connected. The next person trying to connect will face an error message until the screen is reopened using screen -R node. Once th ...

What are the steps to fix a timeout error with React.js and socket.io acknowledgements?

My setup includes a Node.js server and a React.js client application. Data is exchanged between them using socket.io, but I'm running into an issue with implementing acknowledgment. Whenever I try to implement acknowledgment, I receive a timeout error ...

Receiving error messages about missing images in my React project

I am new to programming and I have encountered an issue while running my React project. When I use the command npm start, I noticed that some image resources are not being packaged properly, resulting in certain images disappearing when the website is run ...

When using ajax, you will receive the source code of the page, rather

After searching everywhere, I have only found solutions involving jquery. However, my issue does not involve jquery at all. To solve the problem, I send an ajax string to a php file. The php file processes the data and generates a message string that is ...

The redirect link to Facebook Messenger is functional on desktop browsers but experiences difficulties on mobile browsers

Currently, I am facing an issue with redirecting from a webpage to an m.me/?ref= Facebook link that points to a Facebook Page. The redirection works smoothly on the Desktop Browser and opens the Facebook Messenger as expected. However, when attempting the ...