ngIf failing to pick up on variable updates

Utilizing the greensock animation library to animate various components has presented a problem during the variable update within the onComplete function linked to a *ngIf. Strangely, Angular fails to recognize the variable update within the callback.


Desired outcome:

1. Click on the grey image.
2. The pink image fades out.
3. One of the grey images disappears.

Current behavior:

1. Click on the grey image.
2. The pink image fades out.
3. (No action occurs)
4. Repeat clicking on the grey image.
5. Finally, one of the grey images vanishes.

A relevant plunkr is available for reference...

declare var TweenMax; // Defined in index.html
@Component({
  selector: 'my-app',
  template: `
    <img *ngIf="leftVisible" src="http://placehold.it/350x150" (click)="animate(-1)"/>
    <img *ngIf="rightVisible" src="http://placehold.it/350x150" (click)="animate(1)"/>
    <img #otherImage src="http://placehold.it/350x150/ff00ff/000000"/>
  `,
})
export class App {
  @ViewChild('otherImage') otherImageElement;

  private leftVisible: boolean;
  private rightVisible: boolean;

  constructor() {
    this.leftVisible = this.rightVisible = true;
  }

  private animate(_direction: number){
    var tween = TweenMax.to(this.otherImageElement.nativeElement, 1, {
      opacity: 0,
      onComplete: () => {
        console.log("Animation complete");
        this.rightVisible = false;
      }
    }
  };
}

The console confirms that the callback executes successfully and updates the variable, yet the element tied to the *ngIf does not alter until the grey images are clicked again.

How can I ensure proper updating within the onComplete callback?

Answer №1

For more information on Angular 2, please take a look at the Lifecycle Hooks documentation.

The documentation highlights that in Angular's unidirectional data flow rule, updates to the view are not allowed after it has been composed. Both of these hooks trigger after the component's view has been composed.

Solution1: use ngZone.run to prompt Angular to render the view again.

// Make sure to import ngZone from @angular/core first.
this.ngZone.run(() => {
  console.log("animation complete");
  this.rightVisible = false;
});

Solution2: utilize ChangeDetector to instruct Angular to re-render the view.

import {ChangeDetector} from '@angular/core';

this.rightVisible = false;
this.cd.detectChanges();

Check out this plunker link for an example containing the code provided above.

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 methods can be used to protect an application with spring boot and angular 8 without requiring users to log in?

I am looking to enhance security for an application that leverages angular 8 and spring boot 5. Currently, the application is free form and does not require login to access the UI. Although I have implemented CSRF protection, it is still possible for som ...

Contrast between employing typeof for a type parameter in a generic function and not using it

Can you explain the difference between using InstanceType<typeof UserManager> and InstanceType<UserManager> I'm trying to understand TypeScript better. I noticed in TS' typeof documentation that SomeGeneric<typeof UserManager> ...

Solution: How to fix the error: Invalid component type, 'Draggable' cannot be used with JSX in react-draggable

I encountered an error while working on this Next.js React project Type error: 'Draggable' cannot be used as a JSX component. Its instance type 'Draggable' is not a valid JSX element. The types returned by 'render()&apo ...

Error Encountered: Unable to locate control within nested form array: 'module -> 0 -> view'

I am creating a Form Array with Nesting, using Reactive Forms in Angular 7. I am encountering this error: ERROR Error: Cannot find control with path: 'module -> 0 -> view' I have built the Nested Form but keep getting errors. Please help m ...

It is not possible to use an async function with Ionic 4 ToastController buttons

Incorporating a new function into the handler of my ToastController button to return a promise (in this case: this.navCtrl.navigateForward()) is something I need assistance with. This is what my code looks like: const toast = await this.toastController.c ...

Reactive Extensions - Incorporating interdependent synchronous calls into a fork join without the need for nesting

Looking for a way to avoid nesting synchronous calls that rely on each other and wanting to subscribe at the end result, similar to forkjoin. I came across a solution on stackoverflow (Wait for nested subscribe in angular before continuing with main subscr ...

I keep encountering the issue where nothing seems to be accessible

I encountered an error while working on a project using React and Typescript. The error message reads: "export 'useTableProps' (reexported as 'useTableProps') was not found in './useTable' (possible exports: useTable)". It ...

What is the best way to effectively handle the proxying of objects across multiple levels?

As illustrated in a Stack Overflow thread, utilizing Proxy objects is an effective method for monitoring changes in an object. But what if you need to monitor changes in subobjects? In such cases, you will also have to proxy those subobjects. I am curren ...

execution of synchronized task does not finish

My approach to running Protractor tests in a headless mode using Xvfb may not be the most efficient, so let me outline my high-level requirement first. I am utilizing the angular2-seed and I aim to execute Protractor tests in a headless mode by incorporat ...

What is the best way to bring in local modules within the browser environment using Playwright?

Let me illustrate what I am attempting to achieve: ../src/Foo/Bar.ts represents a local TypeScript file This particular file contains code that is designed to function within a browser environment (it utilizes WebSockets), and therefore needs to be execu ...

Encountering a NullInjectorError in Angular while utilizing dynamic module federation when importing a standalone component along with

My main goal is to develop a shell application acting as a dashboard without routing, featuring multiple cards with remote content (microfrontend standalone component). I have been following a tutorial that aligns closely with my requirements: . The reas ...

Updating the style of different input elements using Angular's dynamic CSS properties

I am seeking guidance on the proper method for achieving a specific functionality. I have a set of buttons, and I would like the opacity of a button to increase when it is pressed. Here is the approach I have taken so far, but I have doubts about its eff ...

Angular is not able to access the value of a promise in a different function after it has been retrieved

I have a form with default values that should be added to the form fields when it appears. There are two functions: #1 for fetching data from the backend and #2 for displaying the form: person$: any; ngOnInit() { this.getPersonData(123) this.buildPer ...

The directive isn't functioning within a submodule

I am facing an issue with getting a directive to function properly in a lazy loaded module. Even after carefully reviewing the documentation and adding the directive to the declarations array of my main module, the directive works fine in the main module b ...

Testing an Angular component that utilizes an AngularJS service: A comprehensive guide

In my hybrid angular application, I am utilizing AngularJS services alongside Angular services. This setup works seamlessly in the application. export function myServiceFactory(i: any): any { return i.get('MyService'); } export const myService ...

Decide using Angular whether a component's value change is due to a recognized alteration

We're currently utilizing the 'switch' feature in DevExtreme and have configured the onValueChanged event to carry out a specific action. However, this event is also triggered whenever the property value of the associated object changes due ...

Angular Signals: How can we effectively prompt a data fetch when the input Signals undergo a change in value?

As I delve into learning and utilizing Signals within Angular, I find it to be quite exhilarating. However, I have encountered some challenges in certain scenarios. I am struggling to come up with an effective approach when dealing with a component that ha ...

Choose Angular Material to dynamically display the state of multiple items as either checked or unchecked

Currently, I am utilizing <mat-select> from Angular Material for multiple choice selection. Is there a particular property that can be set for <mat-option> to determine whether an option should be checked or unchecked based on a parameter? For ...

Showing JSON object in an Angular 2 template展示JSON对象在模

When I execute the following code: stanservice.categoryDetail(this.params.get('id')) .then((data) => { this.category = JSON.stringify(data.res.rows[0]); console.log(JSON.stringify(data.res.rows[0])); }) .catch((error) => { ...

Tips for arranging mat-option in alphabetical order using typescript in Angular 7 Material Design

According to the Angular documentation, there is currently no orderBy pipe available for sorting. It is recommended to implement the sort functionality in the component. However, as a beginner in Angular, I am unsure of how to do this. Can anyone provide a ...