我正在遵循阿波罗教程。最终结果是一个交互式应用程序,允许登录的用户在即将到来的Space-X发射中预定位置。
我刚写完三个突变解析器:login,bookTrips和cancelTrip。 https://www.apollographql.com/docs/tutorial/resolvers.html#mutation
使用3个ID的对象数组作为参数来测试bookTrips会导致错误。 https://graphqlbin.com/v2/K1V7ir
测试登录解析器有效 https://graphqlbin.com/v2/K1V7ir
测试cancelTrip的工作原理 https://graphqlbin.com/v2/K1V7ir
我已经遍历我的代码几次以寻找错字。我注释掉了我的代码版本,并复制/粘贴了本教程中给出的代码,仍然出现相同的错误。
在src / resolvers.js内部
bookTrips: async (_, { launchIds }, { dataSources }) => {
const results = await dataSources.userAPI.bookTrips({ launchIds });
const launches = await dataSources.launchAPI.getLaunchesByIds({
launchIds,
});
return {
success: results && results.length === launchIds.length,
message: results.length === launchIds.length
? 'trips booked successfully'
: `the following launches could not be booked: ${launchIds.filter(
id => !results.includes(id),
)}`,
launches,
};
},
cancelTrip: async (_, { launchId }, { dataSources }) => {
const result = dataSources.userAPI.cancelTrip({ launchId });
if (!result)
return {
success: false,
message: 'failed to cencel trip',
};
const launch = await dataSources.launchAPI.getLaunchById({ launchId });
return {
success: true,
message: 'trip cancelled',
launches: [launch],
};
},
},
在src / datasources / launch.js内部
// returns several launches based on their respective launchIds
getLaunchByIds({ launchIds }) {
return Promise.all(
launchIds.map(launchId => this.getLaunchById({ launchId })),
);
}
// method takes in a flight number and returns the data for a particular launch
async getLaunchById({ launchId }) {
const res = await this.get('launches', { flight_number: launchId });
return this.launchReducer(res[0]);
}
// transform launch data into a shape the schema expects
launchReducer(launch) {
return {
id: launch.flight_number || 0,
cursor: `${launch.launch_date_unix}`,
site: launch.launch_site && launch.launch_site.site_name,
mission: {
name: launch.mission_name,
missionPatchSmall: launch.links.mission_patch_small,
missionPatchLarge: launch.links.mission_patch,
},
rocket: {
id: launch.rocket.rocket_id,
name: launch.rocket.rocket_name,
type: launch.rocket.rocket_type,
},
};
}
在src / datasources / user.js内部
// Takes an object with an array of launchIds and books them for the logged in user
async bookTrips({ launchIds }) {
const userId = this.context.user.id;
if (!userId) return;
let results = [];
// for each launch id, try to book the trip and add it to the results array
// if successful
for (const launchId of launchIds) {
const res = await this.bookTrip({ launchId });
if (res) results.push(res);
}
return results;
}
在我的graphql操场上跑完之后
mutation BookTrips {
bookTrips(launchIds: [67,68,69]) {
success
message
launches {
id
}
}
}
我期望获得成功消息以及刚刚预订的突变ID。
答案 0 :(得分:0)
似乎找不到用户。尝试更改
async bookTrips({ launchIds }) {
const userId = this.context.user.id;
到
async bookTrips({ launchIds }) {
const userId = this.context.user && this.context.user.id;
答案 1 :(得分:0)
仅供参考,我在尝试使用 Apollo 在标头中发送授权参数时遇到了同样的错误:
const currentUserJSON = localStorage.getItem("currentUser") || undefined;
const currentUser =
currentUserJSON !== undefined ? JSON.parse(currentUserJSON) : undefined;
return {
headers: {
...headers,
...(currentUser !== undefined
? { [`Authorization-User-ID`]: currentUser.id }
: {}),
},
};
});
原来的错误是我正在检查 localStorage 是否返回 undefined,当它返回 null 时没有数据。
因此,当 currentUser 为 currentUser.id
时,我的逻辑试图读取 null
。
简单的解决方案:
// Cast nulls to undefined when fetching from localStorage
localStorage.getItem("currentUser") || undefined;