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

What is the correct method for exporting an ES6 module function as a library to be utilized in a Node.js application?

Imagine having a node.js application that does not pass through webpack bundling: Node App const Html = require('./build/ssr-bundle.js'); let result = Html.ssrbundle.render(); console.log(result); Here is my ES6/JSX file, which undergoes web ...

Are there any other methods of using HREF in an <asp:Button> besides OnClientClick for invoking an inline div?

I decided to create a concealed <div> on the same page and tried calling it with href="#", which worked perfectly. However, when I attempted to use the same code in ASP.net, I encountered some issues with Javascript or other factors that prevented it ...

In ReactJS, ensure only a single div is active at any given moment

I'm working on a layout with three divs in each row, and there are multiple rows. Only one div can be selected at a time within a row, and selecting a new div will automatically unselect the previously selected one. Here is a simplified version of my ...

Utilizing Google App Engine for seamless deployment, integrating Ajax for dynamic interactions, and

Using the google App Engine, I am looking to implement javascript (or Ajax) for POSTing a form and updating the target div. The form includes multiple fields and files for transfer. The javascript function I am using is extracted from the "Javascript: The ...

Ways to smoothly navigate to a specific element across various browsers with jQuery animation

This particular piece of code is causing some cross-browser compatibility issues: jQuery('body').animate({scrollTop: target.offset().top}, 300); Interestingly, it works perfectly in Firefox but not in Chrome. A different version of the same co ...

Utilize the asynchronous power of Morgan to quickly display your

After investing a considerable amount of time into this task, I'm uncertain about its feasibility: Creating a reverse lookup of IP addresses and logging it through morgan Express.use(Morgan(async(tokens, req, res) => { async function ip_reverse ...

HTML Highlighting in Angular UI Select

When using UI Select for filtering, the added span tag is showing up as text instead of being rendered as HTML. A picture below demonstrates what I am experiencing. Do you have any thoughts or suggestions? Here is the code for my UI select for reference: ...

Guide on invoking a node.js function from an express-rendered ejs page

My express server currently has a button that triggers a POST request to activate a function in my node.js server. Instead of using a traditional POST request, I am interested in implementing something like AJAX so that the page doesn't reload. Is th ...

Issue with Vue-Validator form validation not functioning properly on JS Fiddle

I'm having trouble with vue-validator on JSFiddle. Can someone please assist in troubleshooting the issue so I can proceed with my main question? Check out JSFiddle Html: <div id="app"> <validator name="instanceForm"> & ...

Using jQuery Accordion within the MVC Framework

I'm new to MVC and considering using an accordion. However, I'm facing issues as the accordion does not appear despite adding all necessary references for jquery accordion and creating the div. Here is my code: @{ ViewBag.Title = "Online Co ...

What is the best way to display an image during the waiting period for an AJAX response?

Can anyone provide some guidance? I'm attempting to use a loading gif while waiting for a response from an ajax request. Unfortunately, the gif is not being displayed when sending an email. I've searched through multiple pages on different platf ...

Utilizing Vue.js to pass a slot to a customized Bootstrap-Vue Table component

I am currently in the process of developing a wrapper for the bootstrap-vue Table component. This particular component utilizes slots to specify cell templates, similar to the following example: <b-table :items="itemsProvider" v-bind="options"> ...

Using Plupload plugin to handle file uploads triggers unexpected page refresh when making Ajax requests

I have implemented the Plupload plugin to facilitate the uploading of multiple files. I have linked the FileUploaded event to the uploader in order to execute additional actions once a file has been uploaded. Below is where I am attaching the event. uploa ...

Retrieve the part of a displayed element

Presently, I am developing a modal system using React. A button is located in the sidebar and the modal is represented as a div within the body. In the render function of the main component of my application, two components are being rendered: MyModal M ...

The ES6 reduce method is not giving the expected result

In Image 1, the output you will see if you log the final array from Snippet 1. My goal is to transform my array to match the format shown in Image 2. I attempted using lodash's _.uniqBy() method [Snippet 2], but the logged output of the reduce varia ...

How can one update transitive dependencies to a specific newer version in npm to address CVE vulnerabilities?

Here are the packages that require upgrading. I attempted to update the version and signature of the packages listed in package-lock.json. However, whenever I run npm i after modifying package-lock.json, the changes made to package-lock.json disappear. ...

Spring 4: The Frustrating Error Code 415 - When Media Type

Every time I run my Java code, I keep getting a 415 error. My project uses Spring 4.1.5 and fasterxml Jackson (core and databind) 2.5.2 @RestController @RequestMapping("/mainvm") public class MainVMController { @RequestMapping(value = "/init",consumes ...

Leveraging data from various Fetch API calls to access a range of

As a beginner with Fetch API and Promises, I have encountered an issue that I hope someone can help me with. My code involves fetching event data with a token, extracting team ids, and using these ids to fetch more information from another endpoint. Every ...

Utilizing the 'as' prop for polymorphism in styled-components with TypeScript

Attempting to create a Typography react component. Using the variant input prop as an index in the VariantsMap object to retrieve the corresponding HTML tag name. Utilizing the styled-components 'as' polymorphic prop to display it as the select ...

Securing client side routes in Vue.js: Best practices

Currently, I am in the process of developing a spa using Vue.js as the front end framework. It interacts with a back-end system that utilizes pure JSON and jsonwebtokens for security. While I am more experienced with the React ecosystem, my new role requir ...