0

It is not that I don't want to update the view , I just don't understand why it does update it when I expect it not to ( since object is updated outside NG).

OK.

I have this simple code:

@Component({
  selector: 'my-app',
  template: `
    <div>
    <input type='button' value="Fill more" (click)="fillMore()"/>
     <ul>
         <li *ngFor="let item of Items ">
         {{item}}
         </li>
     </ul>
    </div>
  `,
})
export class App {

  Items:Array<number> = new Array<number>();

  constructor(private mySignalRService:MySignalRService) 
  {
   this.Items.push(...[1,2,3]); //initial values
  }

  fillMore()
  {
   this.mySignalRService.go(this.Items);
  }
}

As you can see I'm also injecting a service :

@Injectable()
export class MySignalRService
{
   makeDummyDb:Promise<Array<number>>()
   {
       return new Promise( (v,x)=> {
         setTimeout(function (){v([100,200,300]);},800);
       })
   }

   go(arr : Array<number>) : number
   {
     this.makeDummyDb().then((newValues)=>arr.push(...newValues)) ;
     return 5; //this method must return a number 
   }
}

Now - When I click on the button (the "Fill more" button) , I do see the appended items , But when I think of it , it wasn't suppose to update becuase I believe the makeDummyDb:Promise is outside angular's zone ( I might be wrong here)

Question:

Wasn't array update occur outside angular's zone ? How can I simulate a real outside zone so that the code won't work? (for testing)

Plnkr

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Look into this to run something outside of zone.js http://stackoverflow.com/questions/43121400/run-ngrx-effect-outside-of-angulars-zone-to-prevent-timeout-in-protractor – intekhab Apr 17 '17 at 10:14

1 Answers1

2

If your notion is that setTimeout or the Promise will be "outside" the zone, that's not how it works; Angular 2 hijacks setTimeout and setInterval (and as far as I know, when using TypeScript, what is returned by querySelector, which is an IE Element instead of an HTMLElement, forcing a cast to access things like "style", though this doesn't have anything to do with zones, just pointing out that in TS/Angular2, some things may do some things a bit differently). Every time a timeout kicks over, change detection occurs. As far as I can see, that's why your value is getting set, everything to me looks within the zone. You have to take some explicit measures to avoid that.

Small example of working around that:

ngZone.runOutsideAngular(() =>
    Observable.interval(2500).subscribe(() => {
        // async operation
});
Tim Consolazio
  • 4,802
  • 2
  • 19
  • 28
  • Ok so how can I simulate an "outside" zone via simple methods for testing ? – Royi Namir Apr 17 '17 at 10:10
  • Posted example of a workaround. You can check out (there's a lot of docs on this out there but yeah it can be sort of tricky to pull together) https://christianliebel.com/2016/11/angular-2-protractor-timeout-heres-fix/ – Tim Consolazio Apr 17 '17 at 10:16