Home > Blockchain >  New to Typescript/Angular. TS2339 compiling error. *ngIf="x.length > 0;" should be fals
New to Typescript/Angular. TS2339 compiling error. *ngIf="x.length > 0;" should be fals

Time:02-05

I'm following a Typescript/Angular course that is showing me how to use "*ngIf". The instructor is giving an example of an empty array so that it fails the condition and compiles the second set of ul tags. It worked for the instructor, but not for me.

image-box.component.html

<div id="image-box">
    <div >
        <img src="https://images.unsplash.com/photo-1606857521015-7f9fcf423740?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80"/>
        <app-title></app-title>
    </div>
    <div >
        <h3>Contracts</h3>
        <ul *ngIf="contractInComponent.length > 0">
            <li *ngFor="let contract of contractInComponent">
                Service: {{ contract.service }} <br>
                Title: {{ contract.title }}
            </li>
        </ul>
        <ul *ngIf="contractInComponent.length == 0">
            <li>Empty</li>
        </ul>
    </div>
</div>

get-data.service.ts

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

@Injectable({
  providedIn: 'root'
})
export class GetDataService {

  constructor() { }

  getContracts() {
    return [];
  }
}

image-box.component.ts

import { Component, OnInit } from '@angular/core';
//import { ImageBoxService } from './image-box.service';
import { GetDataService } from './get-data.service';

@Component({
  selector: 'app-image-box',
  templateUrl: './image-box.component.html',
  styleUrls: ['./image-box.component.scss']
})
export class ImageBoxComponent implements OnInit {
  contractInComponent;
  constructor(service:
    GetDataService) {
    this.contractInComponent = service.getContracts();
  }

  ngOnInit() {}
}

Compiled with problems:

ERROR

src/app/image-box/image-box.component.html:12:38 - error TS2339: Property 'service' does not exist on type 'never'.

12                 Service: {{ contract.service }} <br>
                                        ~~~~~~~

  src/app/image-box/image-box.component.ts:7:16
    7   templateUrl: './image-box.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component ImageBoxComponent.


ERROR

src/app/image-box/image-box.component.html:13:36 - error TS2339: Property 'title' does not exist on type 'never'.

13                 Title: {{ contract.title }}
                                      ~~~~~

  src/app/image-box/image-box.component.ts:7:16
    7   templateUrl: './image-box.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component ImageBoxComponent.

This works when I explicitly use Booleans. The first ul tag gets ignored and compiles the second set. The output is 0.

image-box.component.html

<div id="image-box">
    <div >
        <!-- <h2>{{ contractInComponent[0].service }}</h2> -->
        <img src="https://images.unsplash.com/photo-1606857521015-7f9fcf423740?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80"/>
        <app-title></app-title>
    </div>
    <div >
        <h3>Contracts</h3>
        <ul *ngIf="false">
            <li *ngFor="let contract of contractInComponent">
                Service: {{ contract.service }} <br>
                Title: {{ contract.title }}
            </li>
        </ul>
        <ul *ngIf="true">
            <li>{{ contractInComponent.length }}</li> <!-- output = 0 -->
        </ul>
    </div>
</div>

get-data.service.ts

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

@Injectable({
  providedIn: 'root'
})
export class GetDataService {

  constructor() { }

  getContracts() {
    return [];
  }
}

CodePudding user response:

Your compiler automatically determines a return type and sees that your getContracts() is always returning undefined. That's why you have the error. If you explicitly add a return type like this.

getContracts() : any {
     return [];   
}

The error will disappear because you tell the compiler it will potentially return something.

CodePudding user response:

I only get an error due to the fact that you are injecting the dependency GetDataService as service but you are not creating the reference to it (aka missing the private word before the service word)

constructor(service:GetDataService){} //causes error
constructor(private service:GetDataService){} //works fine

You can see it running in this StackBlitz replication: https://stackblitz.com/edit/angular-tdcxk7?file=src/test/test.component.ts

  • Related