从下面的 getPlanById
函数中,我收到 TypeError: Cannot read property 'planReducer' of null
错误。我尝试在构造函数中绑定(bind) this
并使用箭头函数。似乎两者都不起作用。还有其他事情在起作用吗?
require('dotenv').config();
const { RESTDataSource } = require('apollo-datasource-rest')
import firebaseInitialize from '../../firebase_initialize'
const firebase = firebaseInitialize()
class PlanData extends RESTDataSource {
constructor() {
super()
this.baseURL = 'https://api.com/'
this.getPlanById = this.getPlanById.bind(this)
}
willSendRequest(request) {
console.log(this.context.headers)
request.headers.set('Auth', this.context.headers.authorization);
}
planReducer(data) {
return {
id: data.plan.id,
image: data.plan.image,
title: data.plan.title
}
}
getPlanById = async ({ planId }) => {
const db = firebase.database()
const ref = db.ref(`plans/${planId}`)
ref.once("value", function(snapshot) {
const data = snapshot.val()
return this.planReducer(data)
}).catch((e) => {
console.log(e)
});
}
}
export default PlanData
最佳答案
this
引用您案例中的 function(snapshot) {...}
闭包。
简单的方法是在闭包外部定义 parent
,然后使用 parent
而不是 this
:
require('dotenv').config();
const { RESTDataSource } = require('apollo-datasource-rest')
import firebaseInitialize from '../../firebase_initialize'
const firebase = firebaseInitialize()
class PlanData extends RESTDataSource {
constructor() {
super()
this.baseURL = 'https://api.com/'
this.getPlanById = this.getPlanById.bind(this)
}
willSendRequest(request) {
console.log(this.context.headers)
request.headers.set('Auth', this.context.headers.authorization);
}
planReducer(data) {
return {
id: data.plan.id,
image: data.plan.image,
title: data.plan.title
}
}
getPlanById = async ({ planId }) => {
const parent = this;
const db = firebase.database()
const ref = db.ref(`plans/${planId}`)
ref.once("value", function(snapshot) {
const data = snapshot.val()
return parent.planReducer(data)
}).catch((e) => {
console.log(e)
});
}
}
但是,您的 returnparent.planReducer(data)
行可能也在执行您不希望它执行的操作:它只是在闭包内返回,而不是 getPlanById
函数。
因此要解决这个问题,请使用async/await
:
require('dotenv').config();
const {RESTDataSource} = require('apollo-datasource-rest')
import firebaseInitialize from '../../firebase_initialize'
const firebase = firebaseInitialize()
class PlanData extends RESTDataSource {
constructor() {
super();
this.baseURL = 'https://api.com/';
this.getPlanById = this.getPlanById.bind(this)
}
willSendRequest(request) {
console.log(this.context.headers);
request.headers.set('Auth', this.context.headers.authorization);
}
planReducer(data) {
return {
id: data.plan.id,
image: data.plan.image,
title: data.plan.title
}
}
getPlanById = async ({planId}) => {
const parent = this;
const db = firebase.database();
const ref = db.ref(`plans/${planId}`);
return await new Promise((resolve) => {
ref.once('value', function (snapshot) {
const data = snapshot.val();
resolve(parent.planReducer(data));
}).catch((e) => {
console.log(e);
// add some sensible error handling here
resolve(null);
});
});
}
}
关于javascript - 如何在类函数中使 this 不为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56637495/