# Angular Problems with renderer

**URL:** <https://discourse.threejs.org/t/angular-problems-with-renderer/42785>\
**Category:** Questions\
**Tags:** angular, resource, webgl-renderer, rendering\
**Created:** [September 21, 2022, 1:55pm UTC](https://discourse.threejs.org/t/angular-problems-with-renderer/42785 "2022-09-21T13:55:01Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sappytree](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/sappytree/32/29708_2.png) [@sappytree](https://discourse.threejs.org/u/sappytree)\
**Post date:** [September 21, 2022, 1:55pm UTC](https://discourse.threejs.org/t/angular-problems-with-renderer/42785/1 "2022-09-21T13:55:01Z")

</div>

I want to use THREEjs with Angular and want to create a good structure. Therefore I am trying to put my render loop into a service.

```javascript
requestAnimationFrame(this.requestRenderer.bind(this));

```

but I get this following error:

```bash
ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'add')

```

I am uncertain if this is even possible:

my page script:

```nohighlight
import {
  AfterViewInit,
  Component,
  ElementRef,
  Input,
  OnInit,
  ViewChild,
} from '@angular/core';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { RenderingServiceService } from '../shared/services/rendering-service/rendering-service.service';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss'],
})
export class Tab1Page implements AfterViewInit {
  @ViewChild('canvas') private canvasRef: ElementRef;

  scene!: THREE.Scene;
  controls!: OrbitControls;

  // Set Light
  light: THREE.DirectionalLight;
  lightProps = { intensity: 1, color: 0xffffff };

  // Set Cube
  geometry = new THREE.BoxGeometry(1, 1, 1);
  material = new THREE.MeshPhongMaterial({ color: 0x44aa88 });
  cubes: THREE.Mesh[] = [];
  camera: THREE.PerspectiveCamera;
  renderer!: THREE.WebGLRenderer;

  constructor(private myrenderService: RenderingServiceService) {}

  ngAfterViewInit(): void {
    // Set Scene
    this.camera = this.myrenderService.setCamerara();
    this.renderer = this.myrenderService.setRenderer(this.canvas);

    // Add to scene
    this.cubes = [
      this.makeInstance(this.geometry, 0x44aa88, 0),
      this.makeInstance(this.geometry, 0x8844aa, -2),
      this.makeInstance(this.geometry, 0xaa8844, 2),
    ];

    this.cubes.forEach((cube) => this.scene.add(cube));

    // Set Light
    this.light = new THREE.DirectionalLight(
      this.lightProps.color,
      this.lightProps.intensity
    );
    this.light.position.set(-1, 2, 4);
    this.scene.add(this.light);

    // Controls
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    // this.animate();
    // requestAnimationFrame(this.render);
    this.myrenderService.requestRenderer(this.scene, this.camera, this.cubes);
  }

  get canvas(): HTMLCanvasElement {
    return this.canvasRef.nativeElement;
  }

  makeInstance(geometry, color, x) {
    const material = new THREE.MeshPhongMaterial({ color });
    const cube = new THREE.Mesh(geometry, material);
    this.scene.add(cube);
    cube.position.x = x;

    return cube;
  }
}

```

my rendering service:

```javascript
import { Injectable } from '@angular/core';
import * as THREE from 'three';

@Injectable({
  providedIn: 'root',
})
export class RenderingServiceService {
  //? Helper Properties (Private Properties);
  camera!: THREE.PerspectiveCamera;
  renderer!: THREE.WebGLRenderer;
  rotationSpeedX = 0.05;
  rotationSpeedY = 0.01;

  // Set Camera Property
  cameraProps = {
    fov: 75,
    aspect: 2,
    near: 0.1,
    far: 5,
  };
  constructor() {}

  setRenderer(canvas) {
    // Set Canvas
    this.renderer = new THREE.WebGLRenderer({ canvas: canvas });
    return this.renderer;
  }

  setCamerara() {
    // Set Camera
    this.camera = new THREE.PerspectiveCamera(
      this.cameraProps.fov,
      this.cameraProps.aspect,
      this.cameraProps.near,
      this.cameraProps.far
    );
    this.camera.position.z = 2;
    return this.camera;
  }

  requestRenderer(scene, camera, cubes) {
    this.renderer.render(scene, camera);
    requestAnimationFrame(this.requestRenderer.bind(this));

    const canvas = this.renderer.domElement;
    this.camera.aspect = canvas.clientWidth / canvas.clientHeight;
    this.camera.updateProjectionMatrix();
    if (this.resizeRendererToDisplaySize(this.renderer)) {
      this.camera.aspect = canvas.clientWidth / canvas.clientHeight;
      this.camera.updateProjectionMatrix();
    }
    this.animateCube(cubes);
  }

  renderrender() {}

  resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const pixelRatio = window.devicePixelRatio;
    const width = canvas.clientWidth * pixelRatio || 0;
    const height = canvas.clientHeight * pixelRatio || 0;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }
  animateCube(cubes) {
    const time = new Date();
    const getTime = time.getTime() * 0.001;
    cubes.forEach((cube) => {
      cube.rotation.x = getTime * this.rotationSpeedX * 100;
      cube.rotation.y = getTime * this.rotationSpeedY * 100;
    });
  }
}

```

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [September 21, 2022, 2:15pm UTC](https://discourse.threejs.org/t/angular-problems-with-renderer/42785/2 "2022-09-21T14:15:52Z")

</div>

In general, you should call `bind()` only once. If you want to keep references to e.g. renderer, scene and camera in a class (like a `World` instance or a view), define an `animate()` function like so:

```nohighlight
function animate() {

	requestAnimationFrame( this._animate );

	this.renderer.render( this.scene, this.camera );

}

```

And `this._animate` is created in its constructor like so:

```nohighlight
this.renderer = ...;
this.camera = ...;
this.scene = ...;

this._animate = animate.bind( this );

```

---

<div class="post-metadata">

**Author:** ![anidivr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/anidivr/32/32924_2.png) [@anidivr](https://discourse.threejs.org/u/anidivr)\
**Post date:** [September 21, 2022, 8:05pm UTC](https://discourse.threejs.org/t/angular-problems-with-renderer/42785/3 "2022-09-21T20:05:46Z")

</div>

Just wanted to point out [angular-three: 🧊 THREE.js integration for Angular 🧊 (github.com)](https://github.com/nartc/angular-three) in case you missed it.

Also, lots of Angular/Three Examples [here](https://github.com/IRobot1/ng3-vr-examples) and [here](https://github.com/IRobot1/ng3-cannon-template)

---

<div class="post-metadata">

**Author:** ![sappytree](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/sappytree/32/29708_2.png) [@sappytree](https://discourse.threejs.org/u/sappytree)\
**Post date:** [September 21, 2022, 9:08pm UTC](https://discourse.threejs.org/t/angular-problems-with-renderer/42785/4 "2022-09-21T21:08:25Z")

</div>

Thanks for your swift reply and explanation @Mugen87😄

I think I’ve understood my problem. Instead of using global variables with “this.”, I try to pass my scene, camera and cube as parameters to the requestRenderer(…) function. It might be a scoping issue because it is not clear if my scene, camera, and cube variables are passed by value or passed by reference. But please correct me if my thought are incorrect.

---

<div class="post-metadata">

**Author:** ![sappytree](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/sappytree/32/29708_2.png) [@sappytree](https://discourse.threejs.org/u/sappytree)\
**Post date:** [September 21, 2022, 9:11pm UTC](https://discourse.threejs.org/t/angular-problems-with-renderer/42785/5 "2022-09-21T21:11:41Z")

</div>

@anidivr oh I’ve actually missed those. Thanks for pointing out those resources! I will look into it. I’ve searched this forum before for useful resources. But found none. I’ve searched in topic “Resource” with the tag “Angular” only one entry. So thanks a lot 😁
