Property 'then' does not exist on type 'false' when building an Angular app in the terminal

I am using an Angular (not AngularJS) application that I run via the terminal using the ng serve command.

Everything builds and I can navigate to the Angular app locally through my browser, however when looking at the terminal I have noticed there are some build errors displayed in red displayed below.

✔ Compiled successfully.
⠋ Generating browser application bundles...
    Error: src/app/components/posting/posting.component.ts:343:78 - error TS2339: Property 'then' does not exist on type 'false | Promise<unknown>'.
      Property 'then' does not exist on type 'false'.

    343 this.getVideoMediaData(file).then(a => this.validateFileAgainstConfig('instagram'));
                                                                                     ~~~~
✔ Browser application bundle generation complete.

My getVideoMediaData() looks like this

    public getVideoMediaData(file) {
        if (typeof file === 'undefined') {
            return false;
        }

        return new Promise((resolve, reject) => {
            this.postingService.getMetadata(file.url).subscribe(
                data => {
                    resolve(data);
                    const errors = data.errors;
                    file.errors = [];
                    if (errors && errors.length > 0 ) {
                        errors.forEach(function(ffmpegError) {
                            file.errors.push({
                                'message': ffmpegError,
                                'validation': 'ffmpeg'
                            });
                        }, this);
                    }
                },
                errorResponse => {
                    reject(errorResponse);
                }
            );
        });
    }

What is causing this & how would be the best approach to fix this issue so I no longer receive this error in the terminal once it has finished building after running ng serve.

Expected outcome
After running ng serve the app builds without any errors

Actual outcome After running ng serve the app builds and displays the "Property ‘then’ does not exist on type ‘false’" error in the terminal.

>Solution :

Your first if doesn’t return a Promise. Wrap false with Promise.resolve(false) or make the method async and you should be fine.

Side-note:

You should check for truthyness of file as it also considers null besides from undefined:

async getVideoMediaData(file): Promise<boolean> {
        if (!file) return false;

        return new Promise((resolve, reject) => {
            this.postingService.getMetadata(file.url).subscribe(
                data => {
                    resolve(data);
                    const errors = data.errors;
                    file.errors = [];
                    if (errors && errors.length > 0 ) {
                        errors.forEach(function(ffmpegError) {
                            file.errors.push({
                                'message': ffmpegError,
                                'validation': 'ffmpeg'
                            });
                        }, this);
                    }
                },
                errorResponse => {
                    reject(errorResponse);
                }
            );
        });

}

Side-note-2:

You should also consider toPromise() (RxJS 6 and lower) or firstValueFrom (RxJS 7^) to transform that service observable into a Promise

async getVideoMediaData(file): Promise<boolean> {
        if (!file) return false;

        // if using RxJS 6 or lower
        const data = await this.postingService.getMetadata(file.url).toPromise()
        // RxJS 7
        const data = await firstValueFrom(
            this.postingService.getMetadata(file.url)
        )
        const errors = data.errors;
        file.errors = [];
        if (errors && errors.length > 0 ) {
            errors.forEach(function(ffmpegError) {
                 file.errors.push({
                     'message': ffmpegError,
                     'validation': 'ffmpeg'
                  });
            }, this);
         }
       return data
}

Side-note-3:

I suggest you restrain yourself from passing anonymous functions and use fat-arrows when dealing with JS arrays as you don’t have to deal with the this mess that JS has. Also using map is better than for-eaching and pushing:

file.errors = Array.from(data.errors ?? []).map(ffmpegError => ({message: ffmpegError, validation: 'ffmpeg'}))

Leave a Reply