Angular TypeError:无法读取未定义的属性“名称”

Posted

技术标签:

【中文标题】Angular TypeError:无法读取未定义的属性“名称”【英文标题】:Angular TypeError: Cannot read property 'name' of undefined 【发布时间】:2021-08-16 09:30:12 【问题描述】:

我想要做的是分开两种方法。但这给我带来了一个问题。当我试图让一个函数在组件初始化上运行时。我想在上传文件时获取文件名并将数据从uploadFile 传递到getUrl event.files[0]

我一直在尝试用顶部的其他值声明一个值,但不能,因为我得到“在初始化之前使用了属性‘文件’。”当我尝试这样做时出错。

上传服务:

import  Injectable, Inject  from '@angular/core';
import  AngularFireStorage  from '@angular/fire/storage';
import firebase from 'firebase/app';
import  User, NgAuthService  from '../auth/auth.service';

@Injectable(
  providedIn: 'root',
)
export class UploadService 
  constructor(private afStorage: AngularFireStorage, @Inject(NgAuthService) private user: User)  
  file: File;
  url = '';
  iUser = this.user.uid;
  basePath = `/uploads/images/$this.iUser`;

  //method to upload file at firebase storage
  async uploadFile(event: any) 
    this.file = event.files[0];
    const filePath = `$this.basePath/$this.file.name`;    //path at which image will be stored in the firebase storage
    await this.afStorage.upload(filePath, this.file);
    if (this.file) 
      this.getUrl();
     else 
      console.log("Select a image please.")
    
  

  //method to retrieve download url
  async getUrl() 
    const filePath = `$this.basePath/$this.file.name`; // error is coming from here.
    const snap = this.afStorage.storage.ref(filePath);
    await snap.getDownloadURL().then(url => 
      this.url = url;  //store the URL
      console.log(this.url);
    );
  

用户配置文件.component.ts:

import  Component, OnInit  from '@angular/core';
import  UploadService  from '../../storage/upload.service';
import  AngularFireStorage  from '@angular/fire/storage';

@Component(
  selector: 'app-user-profile',
  templateUrl: './user-profile.component.html',
  styleUrls: ['./user-profile.component.scss'],
)
export class UserProfileComponent implements OnInit 
  constructor(
    public uploadService: UploadService,
    public afStorage: AngularFireStorage,
    )  

    image = this.uploadService.url;

  ngOnInit() 
    this.uploadService.getUrl();
  

堆栈跟踪错误:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'name' of undefined
TypeError: Cannot read property 'name' of undefined
    at UploadService.<anonymous> (upload.service.ts:30)
    at Generator.next (<anonymous>)
    at tslib.es6.js:76
    at new ZoneAwarePromise (zone.js:1387)
    at __awaiter (tslib.es6.js:72)
    at UploadService.getUrl (upload.service.ts:29)
    at UserProfileComponent.ngOnInit (user-profile.component.ts:19)
    at callHook (core.js:2526)
    at callHooks (core.js:2495)
    at executeInitAndCheckHooks (core.js:2446)
    at resolvePromise (zone.js:1213)
    at new ZoneAwarePromise (zone.js:1390)
    at __awaiter (tslib.es6.js:72)
    at UploadService.getUrl (upload.service.ts:29)
    at UserProfileComponent.ngOnInit (user-profile.component.ts:19)
    at callHook (core.js:2526)
    at callHooks (core.js:2495)
    at executeInitAndCheckHooks (core.js:2446)
    at refreshView (core.js:9456)
    at refreshEmbeddedViews (core.js:10566)

如果需要,我可以提供更多信息或任何内容。

【问题讨论】:

嗨@Slash1y,欢迎来到 ***。您在UploadService 中声明了变量file: File;,但没有为其赋值,因此默认为null。您将在getUrl() 中获得this.file.name未定义名称 我该如何解决这个问题?因为我的项目需要它。我已经尝试了一些东西,但没有运气。 @永顺 @YongShun 我想使用this.file = event.files[0],但由于我没有将任何事件传递给函数,所以它不起作用。因为那是我尝试过但不起作用的东西。当我想使用它时,我确实在函数中提供了参数event: any。你能提供一个解决方案吗?或者还有什么我可以使用并获得相同结果的东西吗? 或者由于您的basePath 包含用户ID,您可以检索basePath 中的所有可用文件并生成下载URL。 但问题是,我希望每次在 ngOnInit 方法上输入我的用户配置文件组件时都调用此方法。这突然需要我提供一个参数,比如“文件名:字符串”。如果您查看组件代码,您就会明白我的意思。 【参考方案1】:

似乎getUrl() 方法希望在调用它时定义this.file.name

一个简单的解决方法是仅在知道name 上的name 属性具有值时才调用getUrl(),例如

if ( this.file && this.file.name ) 
  this.getUrl();
 else 
  console.log("Select a image please.")

或更简单的使用空检查

if ( this.file?.name ) 
  this.getUrl();
 else 
  console.log("Select a image please.")

或者,您可能想要调用getUrl(),而不管您是否真的在this.file = event.files[0]; 行中返回了一个文件。这种情况下需要保证this.file.name不为空;最简单的方法是为this.file.name 甚至this.file 创建一个默认/备用值。

// Fallback for this.file.name
async getUrl() 
    const filePath = `$this.basePath/$this.file.name || 'fallback-filename'`; // will not error, if undefined will use 'fallback-filename' instead.
    const snap = this.afStorage.storage.ref(filePath);
    await snap.getDownloadURL().then(url => 
        this.url = url;  //store the URL
        console.log(this.url);
    );

// Fallback for this.file, i.e. instantiate file with some data and have that overwritten
file: File = 
    name: 'fallback-filename',
    // ...

【讨论】:

我可能让一些人感到困惑。但我想通过在我的组件上的 ngOnInit 函数上运行 getUrl 函数来始终在我的网络应用程序上获取图像。 我想我的问题是,如果event.files[0]undefined,你希望getUrl() 做什么?在这种情况下,您的代码将不知道要获取哪个文件名,因此您需要决定在这种情况下想要发生什么,例如不要调用getUrl(),抛出错误,获取默认文件等等 是的,我的意思是需要重新编码我的 getUrl() 函数。并考虑一些事情。我刚刚找到了一个视频,展示了我想要如何做到这一点。 我想我找到了更好的解决方案,我只需要使用 Firebase 实时数据库来存储图像的链接。这似乎更可行,所以我不必把事情复杂化。

以上是关于Angular TypeError:无法读取未定义的属性“名称”的主要内容,如果未能解决你的问题,请参考以下文章

Angular 6 TypeError:无法读取未定义的属性(读取“长度”)错误

Angular 2:TypeError:无法读取未定义的属性“isRouteActive”

Angular,TypeError:无法读取未定义的属性“排序”

Angular 13 Webpack 异常:TypeError:无法读取未定义的属性(读取“NODE_DEBUG”)

Angular Karma - TypeError:无法读取未定义的属性“_id”

Angular Test Jest - TypeError:无法读取未定义的属性“queryParams”