Issue with Angular ng-repeat not updating after array push

Struggling to grasp Angular concepts such as scopes has been a challenge for me.

Recently, I encountered an issue where ng-repeat was not updating after adding a new 'wire' to my array. I suspected it could be due to the array being out of scope when adding to it, but that didn't seem to be the case.

Below is the code snippet:

<body ng-app="wireApp" ng-controller="AddWireController">
<header>
 <form role="form" class="form">
     <div class="form-group">
        <input type="text" placeholder="Description" class="form-control" name="wireDescription" ng-model="wire.description">
        <input type="text" placeholder="URL" class="form-control" name="wireURL" ng-model="wire.URL">
        <input type="text" placeholder="Tags" class="form-control" name="wireTags" ng-model="wire.tags">
        <input type="text" placeholder="Groups" class="form-control" name="wireGroups" ng-model="wire.groups">
     </div>
     <button class="btn btn-primary btn-block" ng-click="addwire(wire)">Add+</button>
    </form>
</header>
<div id="timeline" ng-controller="ListWireController">
    <div ng-repeat="wire in wires">
         <div class="timeline-entry">
            <div class="timeline-stat">
            <div class="timeline-icon bg-info"><i class="fa fa-envelope fa-lg"></i></div>
            <div class="timeline-time">{{ wire.linLastTouched }}</div>
         </div>
            <div class="timeline-label">
            <h4 class="text-info text-lg">{{ wire.linDescription }}</h4>
            <p>{{ wire.tags }}</p>
         </div>
        </div>
    </div>
</div>
</body>

And here is the angular javascript:

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

//Parent controller
wireApp.controller('AddWireController', ['$scope', function($scope) {

$scope.addwire = function(wire) {
    $.post('/wire/create', wire, function(data) {
        $scope.$broadcast('addwire', data); //emit to children
    });
};

}]);

//Child of AddWireController
wireApp.controller('ListWireController', ['$scope', function($scope) {

$scope.wires = [];

$scope.getwireByGroup = function(groupID) {

    $.get('/wire/grpID=' + groupID, function(data) {
        $.each(data.wires, function(index, key){

            var newKey = key;
            newKey.linLastTouched = jQuery.timeago(newKey.linLastTouched);
            $scope.wires.push(newKey);
        });

    });
};

$scope.$on('addwire', function(event, mass) {
    $scope.addwire(mass);
});

$scope.addwire = function(wire){
    $scope.$apply(function() {
        $scope.wires.push(wire);
    });
}

//init data
$scope.getwireByGroup(0);

}]);

Additional question:

I've noticed that using $broadcast creates a dependency between the two controllers. If I wanted to avoid this dependency, would implementing a factory with promises be the solution? Can you provide an example using the existing code?

EDIT:

Special thanks to Simon H and Keval Bhatt for helping me understand the problem rather than just providing a quick fix.

Below is the revised working code (angular):

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

wireApp.factory('wireFactory', function($http){

var wires = [];

return {
    getwireByGroup: function(groupID){

        $http.get('/wire/grpID=' + groupID)
            .success(function(data) {
                $.each(data.wires, function(index, key){
                    var newKey = key;
                    newKey.linLastTouched = jQuery.timeago(newKey.linLastTouched);
                    wires.push(newKey);
                });
            });

        return wires;

    },

    addwire: function(wire){

        $http.post('/wire/create', wire)
            .success(function(data) {
                wires.push(data);
            });
    } 
}               
});


//Parent controller
wireApp.controller('AddWireController', function($scope, wireFactory) {

 $scope.addwire = function(wire) {
    wireFactory.addwire(wire);
};

});

//Child of AddwireController
wireApp.controller('ListWireController', function($scope, wireFactory) {

$scope.wires = [];

$scope.getwireByGroup = function(groupID) {
    $scope.wires = wireFactory.getwireByGroup(groupID);
};

$scope.getwireByGroup(0);

});

Answer №1

The issue arises from the combination of Angular and jQuery in your code. When you utilize Angular functions like $http, the view gets updated automatically after data is fetched due to a 'digest' process. However, when data is received through $.get in jQuery, Angular is unaware of this and doesn't trigger a view update.

I suggest replacing jQuery with Angular methods whenever possible. If that's not feasible, you can manually update the screen by adding $scope.$apply() every time a screen update is needed.

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

Passing inline CSS styles from parent component to child component in Vue

I am currently using vue.js with vuetify, and I need to position a button on top of a canvas component (managed by the Konva library). I successfully achieved this by using absolute positioning for the button. However, in order to organize my code better, ...

Feeling unsure about starting the project with React?

I am encountering difficulties while setting up my React project. The errors I am facing are hindering the process, and I am seeking assistance. The new React app is being created at the following location: H:\React Projects\react-js. As I try ...

What is the best way to traverse through a nested JSON file with d3.js?

Greetings. I am currently facing a challenge in navigating through a nested JSON file. Below is the JSON data that I need assistance with: {"Id":466,"Name":"korea", "Occurrences": ...

Error: Node.js exceeds maximum call stack size while inspecting an objectlogging or debugging

After defining a class as shown below, I encountered an error stating RangeError: Maximum call stack size exceeded when attempting to review the properties of the Object. var Individual = (function () { function Individual(name, age) { this.na ...

When using electron-build, the node-adodb encountered an error stating: 'Failed to spawn C:WINDOWSSysWOW64cscript.exe'

Utilizing node-adodb.js for reading .mdb files with the following code: const db = require('node-adodb') ipcMain.on('query', (e, p) => { if (!p) return appendFileSync('a.log', new Date().getTime() + ' ' + p.t ...

Create a JavaScript function that adds cells to a table, each containing an input field and a corresponding

I successfully developed a function that appends a table with rows and cells, then fills those cells with data from an array. However, I am now faced with the challenge of modifying it so that the generated cells contain an input field where the value= att ...

The display function in Javascript has a tendency to work sporadically

I’ve been tasked with creating my own tic tac toe game through coding. While I am relatively new to programming, I have a strong passion for it. At the moment, I've set up a basic function to hide only the "O", leaving only the "X" visible on the gr ...

Exploring different pages in an Ionic and AngularJS mobile application

I am brand new to the world of Ionic and AngularJS. I have just started working on a simple project but have hit a roadblock. My goal is, To create a login page and a register page. When a user clicks the register button on the login page, they should be ...

react validation for dropdown, react-datepicker, and hour input at intermittent intervals

I have integrated the following packages into my project :- react-datepicker library for selecting from time and to time date validation with date-fns, moment.js, additional validations using jQuery and lodash libraries/packages If you want to view my pr ...

Is there a method in AngularJS to automatically set app.comment to null if the point is not equal to 1 using front end logic?

Can we verify on the front end in AngularJS if app.point !=1 and app.comment==null? <td> <input type="number" max="5" min="1" ng-init="app.point=5" data-ng-model="app.point"> </td> < ...

Executing Parent function in Reactjs (Triggering Drawer when menu item is clicked using Material-ui)

I'm having some trouble trying to activate the drawer when a user clicks on a menu item. Unfortunately, my current solution is not working as expected. Can anyone provide assistance? Parent import React, { Component } from 'react'; // Impo ...

Error: The function `push` cannot be used on the variable `result` (TypeError)

Here is a snippet from my react component const mockFetch = () => Promise.resolve({ json: () => new Promise((resolve) => setTimeout(() => resolve({ student1: { studentName: 'student1' }, student2: { studen ...

Using AJAX to pass post variables

Here is a link I have: <a class="tag" wi_id="3042" wl_id="3693" for_user_id="441" href="#a"> This link triggers an ajax call. $(".tag").click(function() { var for_user_id = $(this).attr("for_user_id"); var wl_id = $(this).attr("wl_ ...

I am encountering an error when trying to implement ui-grid in my Angular JS project

let application = angular.module("financeApp", ["ui.grid"]); application.controller( "financeController", function($scope, $http) { $http.get("url", "data") .then(function(response) { $scope.resultData = response.data; }, funct ...

The password prompt window refuses to align with the center of the screen. This

I've been struggling to position the Javascript popup notification using the width, height, top, and left parameters in the window.open function. No matter what I attempt, it stubbornly remains in the top-left corner. Can someone offer some guidance o ...

Is there a feature in JavaScript that allows for the creation of URLs?

I created an index view displaying cards (like playing cards) in a grid using BootStrap. Each card is within its own div element, and I implemented a jQuery click handler for each div to open a details page when clicked. The redirect from the index to the ...

Difficulty in dynamically updating custom attributes data in a popover

I am attempting to dynamically insert text into a Bootstrap 3 Popover data-content="" on this demo. My goal is to update the text in the data-content="" attribute by clicking different buttons. I have tried doing this using the following code: $("#poper") ...

What is the process for retrieving the members of an ActiveDirectory 2 group through code?

I have been using ActiveDirectory2 to query LDAP in order to retrieve the users of a specific group, but unfortunately, I have not been successful so far. Here is an example of how I am using it: ad.authenticate(config.USERNAME, config.PASSWORD, function ...

Adjusting the text of a button when hovering over it will also trigger a resizing of the

Currently, I am facing an issue where the bootstrap button's size changes when hovered over. My intention is to have the bootstrap button remain a fixed size while only the text inside it changes using javascript for mouseover and mouseout events. How ...

Setting up redux with Next.js: a step-by-step guide

After setting up redux in this manner, everything is functioning properly. The _app.js file has been reorganized as follows : import App from 'next/app'; import { Provider } from 'react-redux'; import withRedux from 'next-redux-wr ...