Estoy usando una aplicación Angular (no AngularJS) que ejecuto a través de la terminal usando el comando ng serve .
Todo se compila y puedo navegar a la aplicación Angular localmente a través de mi navegador, sin embargo, al mirar la terminal, noté que hay algunos errores de compilación que se muestran en rojo a continuación.
✔ 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. Mi getVideoMediaData() se ve así
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); } ); }); }Qué está causando esto y cómo sería el mejor enfoque para solucionar este problema, de modo que ya no reciba este error en la terminal una vez que haya terminado de compilarse después de ejecutar ng serve.
Resultado esperado Después de ejecutar ng serve, la aplicación se compila sin ningún error
Resultado real Después de ejecutar ng serve, la aplicación se compila y muestra el error "La propiedad 'entonces' no existe en el tipo 'falso'" en la terminal.
Su primer si no devuelve una Promise . Envuelva false con Promise.resolve(false) o haga que el método sea async y debería estar bien.
Nota al margen:
Debe verificar la truthyness del archivo, ya que también considera null además de 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); } ); }); }Nota al margen-2:
También debe considerar toPromise() (RxJS 6 e inferior) o firstValueFrom (RxJS 7^) para transformar ese servicio observable en una 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 }Nota al margen 3:
Le sugiero que se abstenga de pasar funciones anónimas y use fat-arrows cuando trate con matrices JS, ya que no tiene que lidiar con this lío que tiene JS. También usar map es mejor que for-each ing y push:
file.errors = Array.from(data.errors ?? []).map(ffmpegError => ({message: ffmpegError, validation: 'ffmpeg'}))