Monitoring all changes with AngularJS in the ng-init function

When working with an AngularJS controller, I set some variables on the server side using ng-init.

/* Setting variables in server side View */
<div ng-controller="myController" ng-init="myFoo=@myFoo;myBar=@myBar">...</div>

/* Controller logic in myApp.js */
app.Controller("myController", function(){
  // Ensure myFoo and myBar are initialized before proceeding

  $scope.$watch("myFoo", function(n,o){}); //?
  $scope.$watch("myBar", function(n,o){}); //?

  // Perform actions dependent on myFoo and myBar values
  for(i=0; i<myFoo; i++) { console.log(myBar); }
});

The key is to ensure that the for loop is only executed once the myFoo and myBar variables are initialized.

Is there a way to achieve this without resorting to unconventional methods like using $timeout?

Here is a link to a CodePen for reference.

var app = angular.module("myApp", []);
app.controller("myCtrl", ['$scope', '$timeout', function($scope, $timeout) {


  $scope.myFoo = false;
  $scope.myBar = false;
  
  $scope.$watch("myFoo", function(n,o){
    //$timeout(null,1500);    
    console.log("watch > myFoo from: "+o+" to "+n+"; >"+$scope.myFoo);
  });
  $scope.$watch("myBar", function(n,o){
    //$timeout(null,500);
    console.log("watch > myBar from: "+o+" to "+n+"; >"+$scope.myBar);
  });
  
  console.log("> Main thread: myFoo is: " + $scope.myFoo);
  console.log("> Main thread: myBar is: " + $scope.myBar);
 }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl">
  
  <div  ng-init="myFoo=true;myBar=true"></div>
</div>

When we run the code, we observe the following output:

> Main thread: myFoo is: false
> Main thread: myBar is: false
watch > myFoo from: true to true; >true
watch > myBar from: true to true; >true

It's evident that the main thread accesses the variables before they are initialized, which is not ideal!

Answer №1

Executing a function on ng-init in Angular is possible.

var app = angular.module("myApp", []);
app.controller("myCtrl", ['$scope', '$timeout', function($scope, $timeout) {


  $scope.myFoo = false;
  $scope.myBar = false;
  
  $scope.$watch("myFoo", function(n,o){
    //$timeout(null,1500);    
    console.log("watch > myFoo from: "+o+" to "+n+"; >"+$scope.myFoo);
  });
  
  $scope.$watch("myBar", function(n,o){
    //$timeout(null,500);
    console.log("watch > myBar from: "+o+" to "+n+"; >"+$scope.myBar);
  });
  
  $scope.load = function(){  
     
        console.log("> Main thread: myFoo is: " + $scope.myFoo);
        console.log("> Main thread: myBar is: " + $scope.myBar);
    
  }
  
 }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl">
  
  <div  ng-init="myFoo=true;myBar=true;load()"></div>
</div>

Answer №2

If you want to wait for both variables to return before destroying the listeners, you can follow this approach:

var app = angular.module("myApp", []);
app.controller("myCtrl", ['$scope', '$timeout', function($scope, $timeout) {


  $scope.myFoo = false;
  $scope.myBar = false;

  var fooListen = $scope.$watch("myFoo", function(n,o){
    console.log("watch > myFoo from: "+o+" to "+n);
    checkInit();
  });
  var barListen = $scope.$watch("myBar", function(n,o){
    console.log("watch > myBar from: "+o+" to "+n);
    checkInit();
  });

  function checkInit(){
    if($scope.myFoo && $scope.myBar){
      console.log("> Main thread: myFoo is: " + $scope.myFoo);
      console.log("> Main thread: myBar is: " + $scope.myBar);
      //stop the watches
      fooListen();
      barListen();
    }

  }

In this scenario, the code listens for changes in each variable and only executes once both are initialized. To stop the $watches from listening, you can refer to this resource: AngularJS : Clear $watch

Here is an updated code snippet to demonstrate this: https://codepen.io/anon/pen/NvGOQE?editors=1112#anon-login

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

Is it possible to eliminate the arrows from an input type while restricting the change to a specific component?

Is there a way to remove the arrows from my input field while still applying it only to the text fields within this component? <v-text-field class="inputPrice" type="number" v-model="$data._value" @change="send ...

Tips for displaying live data in the rows of Element UI's Table

Recently, I've been working with a table that looks like this. <v-table :data="data"> <v-table-column prop="data.attribute" label="Attribute"> </v-table-column> </v-table> Instead of displaying data.attribute in the co ...

Issue with dynamic imports in express routes

I am currently attempting to incorporate a dynamic import within an express.js router Here is the code snippet I have: HelloWorldController.js export const helloWorld = function (req, res) { res.send('hello world') } router.js export defa ...

Tips for saving an array from the server into a script variable

I'm currently working with the express js framework along with Handlebarsjs as the templating engine. My aim is to pass an array from the router to the view, and then store this array within a script tag. //users is an array res.render('chatRoom ...

Error message found: "Uncaught TypeError: e[n] is undefined while setting up redux store in a reactjs application

Delving into the world of Redux for the first time, I decided to tackle the Todo List example from the official redux.js.org website. After testing the code, everything seemed to be working fine with the redux store initialized only with the reducer as a p ...

Issue with Mongoose Promise failing to transfer data to the following chain

When querying MongoDB using mongoose with promises, I encounter an issue where the result is only accessible in the initial .then(function(results){ // can send the result from here..}). However, when I manipulate the results and attempt to pass them to th ...

The callbackFinished function is not defined in the winwheel library

Every time I attempt to call a function with the callbackFinished property inside the animation of winwheel, I encounter an error stating that the function is not defined, even though it is defined in the same class. import React from 'react' imp ...

JavaScript and JSON interchangeably, the first AJAX response should be rewritten by the second response

I am facing an issue with my code: I have two ajax calls being made on window.load, and it seems like the response from the second AJAX call is overwriting the response from the first one before my function can process it. I'm not sure where I'm ...

Button-click scrolling is our featured feature!

One interesting feature on my website is a button (within a div-element) located in the bottom-right corner. I am now looking to enhance this by adding a jQuery function that enables the user to scroll down the page incrementally simply by clicking and hol ...

Sending Angular base64 image data to the server

I am encountering an issue while attempting to upload a base64 image from Angular to ExpressJS. The image is being created using html2canvas to generate the base64 representation. When I try to upload the imageData in its current format, I receive an error ...

The jQuery animate() method fails to execute animations

I'm currently working on a JavaScript animation project and I've run into some roadblocks. One particular issue I'm facing is with animating the <label>'s margin-top, as it's not behaving as expected. For example: $(' ...

What are the steps to customizing the button bar in the uib-datepicker-popup?

I want to customize the button bar for uib-datepicker-popup. Currently, it is using .btn-info, .btn-danger, and .btn-success for the 'today', 'clear', and 'close' buttons. Is there a way to easily change these to different but ...

Connecting Next.js to a Database: A Step-by-Step Guide

I am interested in developing an application similar to Samsung Health that will involve heavy querying on a database. I am unsure whether it would be more beneficial to create a custom server using Node.js (with Express.js) instead of using the integrate ...

Analyzing JavaScript code coverage through unit testing with Jenkins and SonarQube

We have successfully implemented Jenkins/SonarQube to enforce a requirement that any new code committed by developers must have at least 70% unit test code coverage for Java. However, when it comes to applying the same rule for JavaScript, we encountered s ...

Guide on developing a personalized validation system with Vuetify regulations for verifying the presence of an item

I'm currently working on my first CRUD web app using Vue 2 + Vuetify, but I've hit a roadblock while trying to add validation to a form. Specifically, I need to ensure that no item with the same title already exists in the database. You can view ...

Why won't AngularJS ng-click function properly?

I'm attempting to implement form validation using JavaScript. However, when I include the following line document.getElementById("one").setAttribute("ng-click", "insertData()"); inside the validateForm function, it doesn't work properly after ...

Exploring a JavaScript file with the power of JavaScript and HTML

I have a .js file that contains the following data (excerpt for brevity) var albums= "tracks":[ {"title":"Dunnock","mp3":"Birdsong-Dunnock.mp3", "lyrics":"The Dunnock or hedge sparrow has a fast warbling song often delivered from t ...

What could be causing my component to not refresh when used as a child?

I have been experimenting with some code to track rerenders. The initial approach failed when passing <MyComponent> as a child component. it("should return the same object after parent component rerenders", async () => { jest.useF ...

How to show line breaks in MySQL text type when rendering in EJS

In my MySQL table, I have a column called PROJ_ABOUT with the type TEXT. I have inserted several rows into this column and now I am trying to display this information in my Express.js app using the ejs engine. <h2>About project</h2> <p> ...

Display solely the error message contained within the error object when utilizing the fetch API in JavaScript

I am facing an issue in logging the error message to the console while everything else seems to be working fine. Specifically, I am unable to log only the message such as "email exists" when the email already exists in the system. const submitHandler = a ...