... @Component({ template: ` <div class="container" #container> <canvas #canvas></canvas> <svg #svg></svg> </div> ` }) ... @ViewChild(‘svg') svg: ElementRef; svgns = ‘http://www.w3.org/2000/svg'; createLine(leader, follower) { const line = document.createElementNS(this.svgns, 'line'); TweenMax.set(line, { stroke: `#FFFFFF`, strokeWidth: 3, alpha: 1 }); line.setAttribute('x1', `${follower.x}`); line.setAttribute('y1', `${follower.y}`); line.setAttribute('x2', `${leader.x}`); line.setAttribute('y2', `${leader.y}`); this.svg.nativeElement.appendChild(line); // fade out TweenMax.to(line, 0.5, { alpha: 0 }); } ...
Month: March 2018
Using jQuery.queue() to call Functions Synchronously
This week I was working on a project that required me to add a css class to an element within a sequence of events.
First I wanted to fadeOut()
an array of elements, wait a moment, and then add a class to another element.
Because Javascript is asynchronous, on my first attempt everything executed, just not in the order I had anticipated.
Enter jQuery.queue()
.
This handy little function allows you to pass in a callback with next
as a parameter, enabling you to call jQuery and Javascript synchronously.
someElements.fadeOut() .delay(200) .queue(function(next) { otherElements.removeClass('active'); thisElement.addClass('active'); next(); // continue to next line }); someElements.fadeIn();
Now we can call fadeOut()
on someElements
, handle adding and removing classes after our delay()
and then fade someElements
back in.
Testing time based activities in Angular
When testing time streams or promised based activities use ‘fakeAsync’ and ‘tick’.
For example, given a service:
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; @Injectable() export class CountdownService { // counts down from given number to zero source(num: number): Observable<number> { return Observable.timer(1000, 1000) .map( (v) => num - v) .takeWhile( (v) => v !== -1); } }
To test the CountDown class source method:
// … test setup above, inside describe function it('should count down from 5 to 0', inject([CountdownService], fakeAsync( (service: CountdownService) => { let num: number = undefined; const count = service.source(5).subscribe( (value) => num = value); tick(7000) expect(num).toEqual(0); })));
Wrap the ‘it’ callback function in fakeAsync() which creates a new zone for the asynchronous code to run.
Calling tick() with a time span in ms, simulates the code after that amount of time has passed.
Use tick() with no arguments for promise based code
My expectation is based on what happens after 7 seconds has passed.