所以我正在尝试创建一个新项目(我项目中的一个对象),我正在使用 Apollo Client、Angular 5 和 graphcool 框架。
我只想提一下,我的项目已创建并保存在数据库中,但我希望我的应用程序将我重定向到所有项目所在的页面。它正在重定向我,但新项目未显示在列表中。所以我花时间在互联网上阅读教程,发现我需要订阅事件 createProject。所以我这样做了,但是重定向后项目仍然没有显示在列表中,即使它被创建并保存到数据库中也是如此。我也收到以下错误:
Error: Can't find field allProjects({"first":5,"skip":0,"orderBy":"updatedAt_DESC"}) on object (ROOT_QUERY) {
"allProjects({})": [
{
"type": "id",
"generated": false,
"id": "Project:cjfji3yntbbjh0193m2ijcbzi",
"typename": "Project"
},
{
"type": "id",
"generated": false,
"id": "Project:cjfjjai46blgw0103koujxlex",
"typename": "Project"
},
{
"type": "id",
"generated": false,
"id": "Project:cjfjjezdwbq220193z4bwrgnl",
"typename": "Project"
},
{
"type": "id",
"generated": false,
"id": "Project:cjfjxnqj21fsa01642klbrhsu",
"typename": "Project"
}
],
"_allProjectsMeta": {
"type": "id",
"generated": true,
"id": "$ROOT_QUERY._allProjectsMeta",
"typename": "_QueryMeta"
},
"allSkills({\"filter\":{\"name_contains\":\"a\"}})": [
{
"type": "id",
"generated": false,
"id": "Skill:cjee75u5ocggc0169lncmboub",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee761gnvzde0195pfemfo05",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee767ufb5zx0114yfnj8qnk",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee7b9su7jv70145vsbe9g2p",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee7bi5rb80k0114dm3dznrx",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee7bpwkb82r01148rsqfj0m",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee7by8aamj50195fp7n836n",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee7c368b87o0114nltmfxey",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee7ccpdb8c10114xhea0g4s",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefg99anpihz0114wxyz1rk9",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefg9vhxohew0191fzyahz88",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefgawohp1e00195q18bf7lo",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefgb8q9pj430114b7c8nmhb",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefgbhhcp1kn0195ewwbfjxy",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefgc9wqoi2o0191i2tfnzyd",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefgcj4dqthc0115y0nx0vn7",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjefgcqak7fgl0139phkcm7hj",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjegyq4dr9auf0182diw0it6b",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjegyqjb3al1s01204v40lqlj",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjegyqqazd5xp0121y5mewf8o",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjegyqvqg58fz0160oh5d3s5p",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjegyracbd1b50174pbw32u0h",
"typename": "Skill"
}
],
"allSkills({\"filter\":{\"name_contains\":\"ad\"}})": [
{
"type": "id",
"generated": false,
"id": "Skill:cjee75u5ocggc0169lncmboub",
"typename": "Skill"
},
{
"type": "id",
"generated": false,
"id": "Skill:cjee761gnvzde0195pfemfo05",
"typename": "Skill"
}
]
}.
at readStoreResolver (readFromStore.js:71)
at executeField (graphql.js:90)
at eval (graphql.js:46)
at Array.forEach (<anonymous>)
at executeSelectionSet (graphql.js:40)
at graphql (graphql.js:35)
at diffQueryAgainstStore (readFromStore.js:124)
at readQueryFromStore (readFromStore.js:37)
at InMemoryCache.read (inMemoryCache.js:84)
at InMemoryCache.readQuery (inMemoryCache.js:181)
我正在关注关于 howtographql 的教程,他们正在使用这种方法,所以有可能做到这一点。
我的模式:
export const CREATE_PROJECT_MUTATION = gql`
mutation CreateProjectMutation($name: String!,$description: String!, $skillsIds: [ID!],$startedAt: DateTime!, $endingAt: DateTime!,$type: PROJECT_TYPE, $currency: Currency,$createdById: ID!) {
createProject(
name: $name,
description: $description,
skillsIds: $skillsIds,
startedAt: $startedAt,
endingAt: $endingAt,
type: $type,
currency: $currency,
createdById: $createdById
){
id,
name,
createdBy{
id,
firstName,
lastName
},
updatedAt,
description,
currency,
skills{
id,
name
},
startedAt,
endingAt,
type
}
}
`;
export interface CreateProjectMutationResponse {
loading: boolean;
createProject: Project;
}
export const ALL_PROJECTS_QUERY = gql`
query AllProjectsQuery($first: Int, $skip: Int, $orderBy: ProjectOrderBy){
allProjects(first: $first, skip: $skip, orderBy: $orderBy){
id,
name,
createdBy{
id,
firstName,
lastName
},
updatedAt,
description,
currency,
skills{
id,
name
},
startedAt,
endingAt,
type
}
_allProjectsMeta {
count
}
}
`;
export interface AllProjectsQueryResponse {
allProjects: Project[];
_allProjectsMeta: { count: number };
loading: boolean;
}
// Subscription when project is created
export const NEW_PROJECTS_SUBSCRIPTION = gql`
subscription {
Project(filter: {
mutation_in: [CREATED]
}) {
node {
id
name
createdBy{
id
firstName
lastName
}
updatedAt
description
currency
skills{
id,
name
}
startedAt
endingAt
type
}
}
}
`;
export interface NewProjectSubcriptionResponse {
node: Project;
}
我会把我的课程发给你,以防万一有问题:
export class Project {
id: String;
name: String;
description: String;
createdBy: AppUserDisplay;
updatedAt: Date;
skills: Skill[];
startedAt: Date;
endingAt: Date;
currency: Currency;
type: PROJECT_TYPE;
}
export class AppUserDisplay {
id: String;
firstName: String;
lastName: String;
}
export class Skill {
id: String;
name: String;
}
我用于创建项目的角度组件:
CreateProject(projForm: NgForm) {
const createdById = localStorage.getItem(GC_USER_ID);
if (!createdById) {
console.error('No user logged in');
return;
}
// get the selected project type and replace " " with "_" in the name
this.project_type = this.project_types[Number.parseInt(this.selected_project_type.toString())].replace(/\s/g, '_');
// Formating the date
this.startedAt.setFullYear(this.fromDate.year, this.fromDate.month - 1, this.fromDate.day);
this.endingAt.setFullYear(this.toDate.year, this.toDate.month - 1, this.toDate.day);
// Create the project and save it to the database
const createMutationSubscription = this.apollo.mutate<CreateProjectMutationResponse>({
mutation: CREATE_PROJECT_MUTATION,
variables: {
name: projForm.form.controls.name.value,
description: projForm.form.controls.description.value,
skillsIds: this.choosenSkillsIds,
startedAt: this.startedAt,
endingAt: this.endingAt,
type: this.project_type,
currency: this.currencies[Number.parseInt(this.selected_currency.toString())],
createdById: createdById
},
update: (store, { data: { createProject } }) => {
this.updateStoreAfterCreateProject(store, createProject);
},
}).subscribe((result) => {
// console.log(result);
this.router.navigate(['/all-projects']);
}, (error) => {
alert(error);
});
this.subscriptions = [...this.subscriptions, createMutationSubscription];
}
updateStoreAfterCreateProject (store, createProject): UpdateStoreAfterCreateProjectCallback {
const data = store.readQuery({
query: ALL_PROJECTS_QUERY,
variables: {
id: createProject.id,
first: PROJECTS_PER_PAGE,
skip: 0,
orderBy: 'updatedAt_DESC'
}
});
const allProjects = data.allProjects.slice();
allProjects.splice(0, 0, createProject);
allProjects.pop();
data.allProjects = allProjects;
store.writeQuery({ query: ALL_PROJECTS_QUERY,
variables: {
id: createProject.id,
first: PROJECTS_PER_PAGE,
skip: 0,
orderBy: 'updatedAt_DESC'
}, data });
return;
}
这是我用于显示项目的组件
// When Developer access projects page he can see all projects from db
const getQuery = (variables): Observable<ApolloQueryResult<AllProjectsQueryResponse>> => {
const query = this.apollo.watchQuery<AllProjectsQueryResponse>({
query: ALL_PROJECTS_QUERY,
variables: {
id: localStorage.getItem(GC_USER_ID)
}
});
query
.subscribeToMore({
document: NEW_PROJECTS_SUBSCRIPTION,
updateQuery: (previous: AllProjectsQueryResponse, { subscriptionData }) => {
// Casting to any because typings are not updated
// console.log(<any>subscriptionData);
const newAllProjects = [
(<any>subscriptionData).data.Project.node,
...previous.allProjects
];
return {
...previous,
allLinks: newAllProjects
};
}
});
return query.valueChanges;
};
// 6
const allProjectsQuery: Observable<ApolloQueryResult<AllProjectsQueryResponse>> = Observable
// 6
.combineLatest(this.first$, this.skip$, this.orderBy$, (first, skip, orderBy) => ({ first, skip, orderBy }))
// 7
.switchMap((variables: any) => getQuery(variables));
// 8
const querySubscription = allProjectsQuery.subscribe((response) => {
this.projects = response.data.allProjects;
this.count = response.data._allProjectsMeta.count;
this.loading = response.data.loading;
});
这就是我订阅 createProject 事件的方式,但由于某种原因它不起作用。这是我的 apollo 配置文件:
export class GraphQLModule {
// Inject Apollo and HttpLink
constructor(apollo: Apollo, httpLink: HttpLink) {
const token = localStorage.getItem(GC_AUTH_TOKEN);
const authorization = token ? `Bearer ${token}` : null;
const headers = new HttpHeaders().append('Authorization', authorization);
// Provide the GraphQL endpoint
const uri = 'https://api.graph.cool/simple/v1/cjeb3hlm13hxw017104lj3x5c';
const http = httpLink.create({ uri, headers });
// 1
const ws = new WebSocketLink({
uri: `wss://subscriptions.graph.cool/v1/cjeb3hlm13hxw017104lj3x5c`,
options: {
reconnect: true,
connectionParams: {
authToken: localStorage.getItem(GC_AUTH_TOKEN),
}
}
});
apollo.create({
// 2
link: ApolloLink.split(
// 3
operation => {
const operationAST = getOperationAST(operation.query, operation.operationName);
return !!operationAST && operationAST.operation === 'subscription';
},
ws,
http,
),
cache: new InMemoryCache()
});
}
}
抱歉,我的帖子太长了,我试图解释并尽我所能向您展示我的问题是什么。希望可以有人帮帮我。感谢您的时间。