I found this and online and now trying to put it in TS.
Running the following throws Uncaught TypeError: Cannot set property 'toggle' of null
@Injectable()
export class HomeUtils {
private canvas: HTMLCanvasElement;
private context;
private toggle = true;
constructor() { }
public startNoise(canvas: HTMLCanvasElement) {
this.canvas = canvas;
this.context = canvas.getContext('2d');
this.resize();
this.loop();
}
private resize() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
private loop() {
this.toggle = false;
if (this.toggle) {
requestAnimationFrame(this.loop);
return;
}
this.noise();
requestAnimationFrame(this.loop);
}
private noise() {
const w = this.context.canvas.width;
const h = this.context.canvas.height;
const idata = this.context.createImageData(w, h);
const buffer32 = new Uint32Array(idata.data.buffer);
const len = buffer32.length;
let i = 0;
for (; i < len;) {
buffer32[i++] = ((255 * Math.random()) | 0) << 24;
}
this.context.putImageData(idata, 0, 0);
}
}
I'm lost.
A variable is undefined when it's not assigned any value after being declared. Null refers to a value that is either empty or doesn't exist. null means no value. To make a variable null we must assign null value to it as by default in typescript unassigned values are termed undefined.
To check for undefined in TypeScript, use a comparison to check if the value is equal or is not equal to undefined , e.g. if (myValue === undefined) {} or if (myValue !== undefined) {} . If the condition is met, the if block will run.
TypeScript has a powerful system to deal with null or undefined values. By default null and undefined handling is disabled, and can be enabled by setting strictNullChecks to true.
The "this" keyword always points to the object that is calling a particular method. The type of "this" in an expression depends on the location in which the reference occurs: In a constructor, member function, or member accessor, this is of the class instance type of the containing class.
Methods do not capture this
and are dependent on the caller to call them with the correct this
. So for example:
this.loop() // ok
let fn = this.loop;
fn(); // Incorect this
fn.apply(undefined) // Undefined this
Since you pass loop
to another function requestAnimationFrame
you need to ensure that this
is captured from the declaration context and not decided by requestAnimationFrame
:
You can either pass an arrow function to requestAnimationFrame
private loop() {
this.toggle = false;
if (this.toggle) {
requestAnimationFrame(() => this.loop());
return;
}
this.noise();
requestAnimationFrame(() => this.loop());
}
Or you can make loop an arrow function not a method:
private loop = () => {
this.toggle = false;
if (this.toggle) {
requestAnimationFrame(this.loop);
return;
}
this.noise();
requestAnimationFrame(this.loop);
}
The second approach has the advantage of not creating a new function instance on each call to requestAnimationFrame
, since this will be called a lot, you might want to go with the second version to minimize memory allocations.
It's the call to requestAnimationFrame
. You are passing a function not bound to a context, and so, inside that call to loop
there is no this
.
Change the call to:
requestAnimationFrame(() => this.loop());
Arrow functions, contrarily to normal functions, are bound to this
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With