当我在 Angular 的其他组件中使用它时,服务 class 函数 return 未定义
Service class functions return undefined when i use it inside other components in Agular
我正在使用 Angular 8.
我在服务 class 中创建了一个名为 getUserInfo()
的函数,其中 returns 有关使用云服务 Firestore 的用户的信息。
问题是,当我在服务 class 中显示结果时,它已被定义并完美运行,但在组件内部,结果未定义。
我想我知道错误是什么:当我在组件内部调用函数时,它返回 undefined
因为函数需要一些时间从数据库中检索数据,但我不知道知道如何修复它或改用什么?
RxJS 修复了吗?
我已经尝试过路由器解析器,但它也没有用。
这是我在服务中使用的功能class
getUserInfo() {
this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get().then(doc => {
return doc.data()
})}
以下是我想使用服务 class 功能的组件:
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth/auth.service';
@Component({
selector: 'app-super-admin',
templateUrl: './super-admin.component.html',
styleUrls: ['./super-admin.component.css']
})
export class SuperAdminComponent implements OnInit {
user;
constructor(private authService: AuthService) { }
ngOnInit() {
this.user = this.authService.getUserInfo();
}
}
简短的回答是:是的,RxJS 正在解决您的问题。
如您所料,服务器的响应需要一些时间才能return 应用到您的应用程序。
您的组件需要订阅此异步应答,并且仅在收到响应时执行所需的操作。
因此,您需要摆脱服务中的 Promise,只需要 return 对 Firebase 的调用
getUserInfo() {
return this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get();
}
而在您的组件中,您需要执行类似的操作:
ngOnInit() {
this.authService.getUserInfo().subscribe(response => {
/* Use `response` as the answer from the server and do whatever you need to do */
console.log(response); // Use this to inspect the response from the server
});
}
this.user = this.authService.getUserInfo();
是的,你是对的。此时,authService.getUserInfo()
尚未解决。(另外,您的 getUserInfo()
方法中没有 return 语句)。
我能想到 2 种方法来解决这个问题。
this.authService.getUserInfo().then(u => this.user = u);
RxJS 方式:
getUserInfo() {
return from(this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get());
}
/* ... */
this.authService.getUserInfo()
.subscribe(u => this.user = u);
更多关于如何将承诺转换为可观察的。
更好的方法是使用 Rxjs,因为它通常与 angular 一起使用,所以我肯定会推荐它。但是,如果您正在寻找没有它的解决方案,您始终可以使用 Promises。
所以你面临的问题是代码在从服务器接收数据之前正在执行。您可以通过在服务内承诺对 firestore 的调用并返回一个 Promise 来解决这个问题,然后您可以在组件内调用 Promise。
所以代码变成:
服务 Class
getUserInfo() {
let promise = new Promise( (resolve,reject) => {
this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get().then(doc => {
resolve(doc.data());
}).catch(er => {
reject(er);
})
}
return promise;
);
然后在组件ts文件中可以做:
ngOnInit() {
this.authService.getUserInfo().then(data => {
this.user = data;
});
}
希望对您有所帮助!
我在 this stackblitz 中重新创建了你的场景,这是 工作 很好
util.service.ts
import { Injectable } from '@angular/core';
@Injectable()
export class UtilService {
constructor() { }
getUserInfo() {
return new Promise((res,rej) => {
this.getDelayedData((data) => {
res(data)
});
});
}
getDelayedData(call){
setTimeout(()=> {
call('here your data');
}, 1500)
}
}
app.component.ts
import { Component } from '@angular/core';
import { UtilService } from './util.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
constructor(public util: UtilService) {
this.util.getUserInfo().then((data : string) => {
this.name = data;
console.log(data)
})
}
}
我正在使用 Angular 8.
我在服务 class 中创建了一个名为 getUserInfo()
的函数,其中 returns 有关使用云服务 Firestore 的用户的信息。
问题是,当我在服务 class 中显示结果时,它已被定义并完美运行,但在组件内部,结果未定义。
我想我知道错误是什么:当我在组件内部调用函数时,它返回 undefined
因为函数需要一些时间从数据库中检索数据,但我不知道知道如何修复它或改用什么?
RxJS 修复了吗?
我已经尝试过路由器解析器,但它也没有用。
这是我在服务中使用的功能class
getUserInfo() {
this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get().then(doc => {
return doc.data()
})}
以下是我想使用服务 class 功能的组件:
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth/auth.service';
@Component({
selector: 'app-super-admin',
templateUrl: './super-admin.component.html',
styleUrls: ['./super-admin.component.css']
})
export class SuperAdminComponent implements OnInit {
user;
constructor(private authService: AuthService) { }
ngOnInit() {
this.user = this.authService.getUserInfo();
}
}
简短的回答是:是的,RxJS 正在解决您的问题。
如您所料,服务器的响应需要一些时间才能return 应用到您的应用程序。
您的组件需要订阅此异步应答,并且仅在收到响应时执行所需的操作。
因此,您需要摆脱服务中的 Promise,只需要 return 对 Firebase 的调用
getUserInfo() {
return this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get();
}
而在您的组件中,您需要执行类似的操作:
ngOnInit() {
this.authService.getUserInfo().subscribe(response => {
/* Use `response` as the answer from the server and do whatever you need to do */
console.log(response); // Use this to inspect the response from the server
});
}
this.user = this.authService.getUserInfo();
是的,你是对的。此时,authService.getUserInfo()
尚未解决。(另外,您的 getUserInfo()
方法中没有 return 语句)。
我能想到 2 种方法来解决这个问题。
this.authService.getUserInfo().then(u => this.user = u);
RxJS 方式:
getUserInfo() {
return from(this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get());
}
/* ... */
this.authService.getUserInfo()
.subscribe(u => this.user = u);
更好的方法是使用 Rxjs,因为它通常与 angular 一起使用,所以我肯定会推荐它。但是,如果您正在寻找没有它的解决方案,您始终可以使用 Promises。
所以你面临的问题是代码在从服务器接收数据之前正在执行。您可以通过在服务内承诺对 firestore 的调用并返回一个 Promise 来解决这个问题,然后您可以在组件内调用 Promise。
所以代码变成:
服务 Class
getUserInfo() {
let promise = new Promise( (resolve,reject) => {
this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get().then(doc => {
resolve(doc.data());
}).catch(er => {
reject(er);
})
}
return promise;
);
然后在组件ts文件中可以做:
ngOnInit() {
this.authService.getUserInfo().then(data => {
this.user = data;
});
}
希望对您有所帮助!
我在 this stackblitz 中重新创建了你的场景,这是 工作 很好
util.service.ts
import { Injectable } from '@angular/core';
@Injectable()
export class UtilService {
constructor() { }
getUserInfo() {
return new Promise((res,rej) => {
this.getDelayedData((data) => {
res(data)
});
});
}
getDelayedData(call){
setTimeout(()=> {
call('here your data');
}, 1500)
}
}
app.component.ts
import { Component } from '@angular/core';
import { UtilService } from './util.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
constructor(public util: UtilService) {
this.util.getUserInfo().then((data : string) => {
this.name = data;
console.log(data)
})
}
}