Javascript 角度类型错误:无法读取属性';名称';未定义的

Javascript 角度类型错误:无法读取属性';名称';未定义的,javascript,angular,typescript,firebase,firebase-storage,Javascript,Angular,Typescript,Firebase,Firebase Storage,我想做的是分开两种方法。但这给我带来了一个问题。当我试图在组件init上运行一个函数时。我想在上传文件时获取文件名,并将数据从uploadFile传递到getUrl事件文件[0] 我一直试图与顶部的其他值一起声明一个值,但无法,因为我得到“属性‘file’在初始化之前已被使用。”尝试这样做时出错 上载服务: import { Injectable, Inject } from '@angular/core'; import { AngularFireStorage } from '@angula

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

我一直试图与顶部的其他值一起声明一个值,但无法,因为我得到“属性‘file’在初始化之前已被使用。”尝试这样做时出错

上载服务:

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);
    });
  }
}
user-profile.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)
错误错误:未捕获(承诺中):TypeError:无法读取未定义的属性“name”
TypeError:无法读取未定义的属性“name”
在上传服务。(upload.service.ts:30)
在Generator.next()处
在tslib.es6.js:76
在新的ZoneAwarePromise(zone.js:1387)
在等待者(tslib.es6.js:72)
在UploadService.getUrl(upload.service.ts:29)
在UserProfileComponent.ngonit(user profile.component.ts:19)
在callHook(core.js:2526)
在callHooks(core.js:2495)
在executeInitAndCheckHooks(core.js:2446)
在resolvePromise(zone.js:1213)
在新ZoneAwarePromise(zone.js:1390)
在等待者(tslib.es6.js:72)
在UploadService.getUrl(upload.service.ts:29)
在UserProfileComponent.ngonit(user profile.component.ts:19)
在callHook(core.js:2526)
在callHooks(core.js:2495)
在executeInitAndCheckHooks(core.js:2446)
在refreshView(core.js:9456)
在RefreshEmbeddedView上(core.js:10566)

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

方法
getUrl()
要求调用时定义
this.file.name

一个简单的修复方法是,当您知道
this.file
上的
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);
    });
}


你好@Slash1y,欢迎来到StackOverflow。您可以声明变量
file:file,但未为其赋值,因此默认为
null
。您将在
getUrl()
中获得
this.file.name
的未定义名称。如何解决此问题?因为我的项目需要它。我试过一些东西,但运气不好@YongShun@YongShun我想为它使用
this.file=event.files[0]
,但由于我没有将任何事件传递给函数,因此它无法工作。因为这是我尝试过但不起作用的事情。当我想使用时,我确实在函数中提供了参数
event:any
。你能提供一个解决方案吗?或者,我还可以使用其他方法来获得相同的结果吗?或者,由于您的
basePath
包含用户id,您可以检索basePath中的所有可用文件并生成下载URL。但问题是,每次我在ngOnInit方法上输入我的用户配置文件组件时,我都希望获得此方法。这突然需要我提供一个参数,比如“filename:string”。如果你看一下组件代码,你就会明白我的意思。我可能把一些人弄糊涂了。但是我想通过在我的组件上运行
ngOnInit
函数上的
getUrl
函数,始终在我的web应用程序上获取图像。我想我的问题是,如果
event.files[0]
undefined
,你希望
getUrl()
做什么?在这种情况下,您的代码不知道要获取哪个文件名,因此您需要决定在这种情况下希望发生什么,例如,不要调用
getUrl()
,抛出错误,无论如何获取默认文件,等等。我的意思是需要重新编写我的
getUrl()
函数。考虑到一些事情。我确实找到了一个视频,它展示了我想怎么做。我想我找到了一个更好的解决方案,我只需要使用Firebase实时数据库来存储到图像的链接。这似乎更可行,所以我不必把事情复杂化。
// Fallback for this.file, i.e. instantiate file with some data and have that overwritten
file: File = {
    name: 'fallback-filename',
    // ...
}