Tips for Waiting for Binding in an Angular 1.5 Component (No Need for $scope.$watch)

Currently, I am in the process of developing an Angular 1.5 directive and have encountered a frustrating issue related to manipulating data that is not yet available.

Below is a snippet of my code:

app.component('formSelector', {
  bindings: {
    forms: '='
  },
  controller: function(FormSvc) {

    var ctrl = this
    this.favorites = []

    FormSvc.GetFavorites()
    .then(function(results) {
    ctrl.favorites = results
    for (var i = 0; i < ctrl.favorites.length; i++) {
      for (var j = 0; j < ctrl.forms.length; j++) {
          if (ctrl.favorites[i].id == ctrl.newForms[j].id) ctrl.forms[j].favorite = true
      }
     }
    })
}
...

Essentially, I am fetching favorites via AJAX and then comparing them to the list of forms that are bound within the directive.

The issue arises from the fact that the promise is resolved before the binding is actually populated... resulting in 'ctrl.forms' still being undefined when the loop is executed!

Is there a way to overcome this hurdle without resorting to using $scope.$watch, which contradicts the 1.5 component approach?

Answer №1

Encountering a comparable problem, I found a solution to prevent calling the component until the necessary value is prepared:

<form-selector ng-if="asyncValue" forms="asyncValue" ></form-selector>

Answer №2

Utilizing the latest lifecycle hooks, particularly $onChanges, allows you to identify the initial change of a binding by utilizing the isFirstChange method. Discover more about this here.

Check out this example:

<div ng-app="app" ng-controller="MyCtrl as $ctrl">
  <my-component binding="$ctrl.binding"></my-component>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js"></script>
<script>
  angular
    .module('app', [])
    .controller('MyCtrl', function($timeout) {
      $timeout(() => {
        this.binding = 'initial value';
      }, 750);

      $timeout(() => {
        this.binding = 'new value';
      }, 1500);
    })
    .component('myComponent', {
      bindings: {
        binding: '<'
      },
      controller: function() {
        // Implement es6 destructuring for precise extraction
        this.$onChanges = function({binding}) {
          if (angular.isDefined(binding)) {
            console.log({
              currentValue: binding.currentValue, 
              isFirstChange: binding.isFirstChange()
            });
          }
        }
      }
    });
</script>

Answer №3

The individual who initiated the post stated :

the commitment is being honored even before the connection is set... so that when I execute the loop, ctrl.forms is still undefined

Starting from AngularJS version 1.5.3, we now have lifecycle hooks and to address the question posed by the original poster, you simply need to shift the code that relies on the bindings being fulfilled inside $onInit():

$onInit() - Executed on each controller after all controllers on an element have been constructed and had their bindings initialized (and prior to the pre & post linking functions for the directives on this element). This is a suitable location to include initialization code for your controller.

Therefore, in the given example:

app.component('formSelector', {
  bindings: {
    forms: '='
  },
  controller: function(FormSvc) {
    var ctrl = this;
    this.favorites = [];

    this.$onInit = function() {
      // At this point, bindings have been resolved.
      FormSvc
          .GetFavorites()
          .then(function(results) {
            ctrl.favorites = results;
            for (var i = 0; i < ctrl.favorites.length; i++) {
              for (var j = 0; j < ctrl.forms.length; j++) {
                if (ctrl.favorites[i].id == ctrl.newForms[j].id) {
                  ctrl.forms[j].favorite = true;
                }
              }
            }
          });
    }
}

Hence, while there exists a $onChanges(changesObj), $onInit() is specifically relevant to the initial inquiry about when we can be certain that bindings have been completed.

Answer №4

I encountered a similar issue and came across a valuable article that provided the solution I needed.

Upon loading my page, an ajax call is made to the server and my component relies on the response from this ajax call for proper functioning. To address this requirement, I implemented the following:

this.$onChanges = function (newObj) {
      if (newObj.returnValFromAJAX)
        this.returnValFromAJAX = newObj.returnValFromAJAX;
    };

Following this implementation, my component now operates flawlessly. It should be noted that Angular 1.5.6 was used for this reference.

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

Angular JS appears to be failing to properly establish values in the Dropdownlist

I have a project requirement to connect a dropdownlist with MVC and angular JS. Here is my attempt: var app1 = angular.module('Assign', []) app1.controller('SAPExecutive_R4GState', function ($scope, $http, $window) { // alert(UMS ...

Unable to locate a React component module that has been published

After successfully publishing a React component to NPM, I encountered an issue when trying to use it in another project - I couldn't find the module! Module not found: Can't resolve 'react-subreddit-posts' in '/Users/kyle.calica/C ...

Identifying the moment when attention shifts away from an element

Is it possible to detect when focus occurs outside an element without relying on global selectors like $(document), $(body), or $(window) for performance reasons? If achieving this without global selectors is not feasible, provide a provable reason expla ...

Implementing Google Ads Code in NextJS for Automated Units

I'm currently working on a NextJS project and I need to integrate the Google AdSense code for automatic ads. The Google ad code I have is: <script async src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${process.env. ...

Once the recursive function executes (utilizing requestAnimationFrame), socket.emit can finally be triggered

My current issue involves sending an array to my server from the client side using a recursive function, but the responses from the server are delayed and only arrive after the recursive function completes. I'm uncertain whether the problem lies with ...

Fatal syntax error encountered when attempting to define a JavaScript object

Hey, I'm just starting out with JavaScript and I'm encountering a syntax error with the getValue() function in the code below. Can someone please assist me in solving it? let obj = { x:1, function getValue(){ console.log("hello") } } ...

When attempting to delete, I encounter an error stating that $index is undefined

I am currently working on a project that involves Angular and PHP. I have encountered an issue while trying to delete some information, even though the function seems to be retrieving the data correctly. I'm puzzled as to why it is not working as expe ...

Enhance PHP search functionality by showcasing hidden auto-complete suggestions in real-time

I am attempting to showcase unlisted search results that can be clicked on to redirect the user to a specific HTML page based on data retrieved from a MySQL database. My development environment is PhoneGap. Thus far, I have successfully set up a basic PH ...

The Challenge of Iterating Through an Array of Objects in Angular Components using TypeScript

Could someone please explain why I am unable to iterate through this array? Initially, everything seems to be working fine in the ngOnInit. I have an array that is successfully displayed in the template. However, when checking in ngAfterViewInit, the conso ...

Posting several pictures with Protractor

In my test suite, I have a specific scenario that requires the following steps: Click on a button. Upload an image from a specified directory. Wait for 15 seconds Repeat Steps 1-3 for all images in the specified directory. I need to figure out how to up ...

Are there any additional features available in NetSuite that allow for viewing multiple pages within a PDF document?

I'm looking to compile a list of all available pick tickets and then consolidate them into a single PDF file. Unfortunately, I am only able to generate one page per ID. var transactionFile = render.pickingTicket({ entityId: 501, printMode: render.Pri ...

Having difficulty requesting an API in Next.js that relies on a backend cookie

1: When a user logs in, I generate a refresh token and create a cookie using 'cookie-parser'. This cookie is then sent to the path '/user/refresh-token' res.cookie('refreshtoken', refreshtoken, { httpOnly: true, ...

Store my JSON data in a separate file and then reference it in my controller

Hello, I am currently working on an AngularJS application development project. Within my JSON data, I have information structured like this: angular.module('app', []).controller('MainController', ['$scope', function($scope) { ...

Next.js is able to generate a unique URL that strictly handles code execution without any visual elements

Currently, I am in the process of developing a new website using NextJS. One issue that has come up involves a password reset verification endpoint. After a user initiates a password reset, it is sent to the API for processing and then redirected back to ...

Refreshing Ajax in a different tab causes the selectize element to become unbound from the editing form in Rails 5

In my Rails 5.1 application, I have multiple views with the main view being the calls index view. In this view, I perform an ajax refresh of partials and use a callback to re-initialize the selectize JS element in the calls/index view as shown below: < ...

hiding the UI filter with AngularJS: a step-by-step guide

$scope.tableOptions = { "aLengthMenu": [[10, 50, 100, -1], [10, 50, 100, 'All']], "searching": false, "paging": true, "info": false, "lengthChange": false }; Visit this link for more information: ...

Error message: The function pokemon.map does not exist

I'm new to learning react and I've been working on creating a react app using the pokemon API. However, I've encountered an error that says TypeError: pokemon.map is not a function. I'm unsure why .map is not recognized as a function in ...

Steps for deactivating a button until the form has been submitted

Click here for the Fiddle and code sample: $(".addtowatchlistform").submit(function(e) { var data = $(this).serialize(); var url = $(this).attr("action"); var form = $(this); // Additional line $.post(url, data, function(data) { try { ...

Generating an associative array on the fly

I am interested in transforming a hash by creating nested keys and then adding another hash at the end. For example... var hash_a = {'foo': 'bar'} var hash_b = {'alpha': 'beta'} var array = ['a', 'b& ...

I'm having trouble getting my object to display using ng-repeat in Angular. Can anyone help me understand what I'm missing?

My goal was to add an object to an array upon clicking an event, which I successfully achieved. However, the objects are not displaying in the ng-repeat as ordered. Can you help me figure out what's missing? angular.module('app', []); an ...