0

I am working on a project which will need to migrate all instances of the old Http to utilize the new HttpClient provided by Angular. But I am having issues with the migration of one of my methods. I get this error ERROR TypeError: Cannot read properties of null (reading 'text') at main.js

Old Method:

ngAfterViewInit(): void {

    var header = this.header;
    if (header == null)
        return;

    var params = new URLSearchParams();

    params.set('manufacturerCode', `${header.manufacturerCode || 0}`);
    params.set('typeCode', `${header.typeCode || 0}`);
    params.set('typeRevisionCode', `${header.typeRevisionCode || 0}`);
    params.set('protocol', `${header.protocol || 0}`);
    params.set('serialNumber', header.serialNumber);
    params.set('tag', header.tag);

    this.http.get(`./api/devices/device-icon`, { search: params }).pipe(map((response: Response) => response.text())).subscribe(data => {

        let source: string;

        if (data != null && data.length > 0)
            source = `data:image/x-icon;base64,${data}`;
        else
            source = './assets/Default_Device_Icon.ico'; // use the default device icon

        this.renderer.setElementAttribute(this.elementRef.nativeElement, 'src', source);
        this.invisible = false;
    });
}

New Method:

ngAfterViewInit(): void {

    var header = this.header;
    if (header == null)
        return;

    var params = new HttpParams();

    params.set('manufacturerCode', `${header.manufacturerCode || 0}`);
    params.set('typeCode', `${header.typeCode || 0}`);
    params.set('typeRevisionCode', `${header.typeRevisionCode || 0}`);
    params.set('protocol', `${header.protocol || 0}`);
    params.set('serialNumber', header.serialNumber);
    params.set('tag', header.tag);

    this.httpClient.get(`./api/devices/device-icon`, { params, responseType: 'text'})
        .pipe(map((response: any) => response.text()))
        .pipe(takeUntil(this.ngUnsubscribe))
        .subscribe(async data => {
            let source: string;

            if (data != null && (await data).length > 0)
                source = `data:image/x-icon;base64,${data}`;
            else
                source = './assets/Default_Device_Icon.ico'; // use the default device icon

            this.renderer.setAttribute(this.elementRef.nativeElement, 'src', source);
            this.invisible = false;
        });
}

1 Answer 1

1

This is why you don't cast to type any : ) . If you remove that, the compiler will tell you that response.text() is not a function, and hovering over the response tells you it is already a string. You've already supplied the responseType as text so that is what you get back.

this.httpClient.get(`./api/devices/device-icon`, { params, responseType: 'text'})
        // Removed the map call
        .pipe(takeUntil(this.ngUnsubscribe))

Also, the way you set HttpParams is doing nothing. set returns a value rather than modifying in place. You can do it like this:

    const params = new HttpParams()
      .set('manufacturerCode', `${header.manufacturerCode || 0}`)
      .set('typeCode', `${header.typeCode || 0}`)
      .set('typeRevisionCode', `${header.typeRevisionCode || 0}`)
      .set('protocol', `${header.protocol || 0}`)
      .set('serialNumber', header.serialNumber)
      .set('tag', header.tag);

No need to use async await inside a subscribe callback. And please just use if (data), this will be false for null, undefined, empty string, NaN, and the number 0 (the string "0" is true). https://developer.mozilla.org/en-US/docs/Glossary/Truthy

.subscribe((data) => {
        let source: string;
        if (data) source = `data:image/x-icon;base64,${data}`;
        else source = './assets/Default_Device_Icon.ico'; // use the default device icon

or simply use the ternary operator

        const source = data
          ? `data:image/x-icon;base64,${data}`
          : './assets/Default_Device_Icon.ico'; // use the default device icon
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.