Reputation: 507
I am trying to get to grips with the GraphQL schema language as part of a work project. I'm running into problems I think because I'm not sure how to write the resolver for a particular data structure I need to use. I have some data for an appointment management system I am writing. There are at this point three collections - Staff, Account, and Booking. A simplified version of the typical json data looks like this:
Staff: {
id: 0,
Name: 'Joe Blogs',
Speciality: 'Fitter'
}
Account: {
id: 0,
Name: 'Fred Foo',
Company: 'Acme Holdings',
staffId: 0
}
Booking: {
id: 0,
Date: '2018-03-23',
staffId: 0,
accountId: 0,
AssignedStaff: [
{id: 0, staffId: 1},
{id: 1, staffId: 3}
]
}
So, a booking will relate to a particular account and be owned by a particular staff member. It will also have an arbitrary number of other staff assigned to it. My GraphQL schema looks like this:
type Staff {
id: Int!
Name: String!
Speciality: String!
accounts: [Account]
bookings: [Booking]
}
type Account {
id: Int!
Name: String!
Company: String!
staff: Staff!
bookings: [Booking]
}
type Booking {
id: Int!
Date: String!
staff: Staff!
account: Account!
AssignedStaff: [AssignedStaff]
}
type AssignedStaff {
id: Int!
staff: Staff!
}
I have working resolvers for the relationships between Staff and Account and Booking working properly. Where I am having problems is with writing a resolver for the assigned staff on a booking. I am doing the development using static dummy data for the time being. The working resolver functions look like this:
Account: {
bookings (account) {
return booking.filter(booking => booking.accountId === account.id)
},
staff (account) {
return staff.find(staff => staff.id === account.staffId)
}
},
Booking: {
account (booking) {
return account.find(account => account.id === booking.accountId)
},
staff (booking) {
return staff.find(staff => staff.id === booking.staffId)
}
},
Staff: {
accounts (staff) {
return account.filter(account => account.staffId === staff.id)
},
bookings (staff) {
return booking.filter(booking => booking.staffId === staff.id)
}
}
and they work fine. I can do e.g. a query like this:
staff(id: 0){
Name
accounts {
Name
bookings {
Date
}
}
}
and it works, the data returned is exactly what I expect. The problem arises when I try to return data about the assigned staff on a booking. I have a resolver for AssignedStaff which currently looks like this:
AssignedPhotographer: {
staff(booking) {
return staff.filter(staff => staff.id === booking.AssignedStaff.staffId)
}
}
but when I run a query against it like this for instance:
staff(id: 0){
Name
accounts {
Name
bookings {
Date
AssignedStaff {
staff{
Name
}
}
}
}
}
The data I get back has an array of null values for AssignedStaff. The number of nulls matches the number of assigned staff for the booking, but it seemingly is not linking to the Staff type properly. If I just request the ids of the assigned staff for a booking like this:
staff(id: 0){
Name
accounts {
Name
bookings {
Date
AssignedStaff {
id
}
}
}
}
It works ok and gives me back the correct data. I'm guessing that the problem is with the way I have done my resolvers, probably specifically with the AssignedStaff resolver. Can anybody please tell me what I'm doing wrong?
Upvotes: 0
Views: 11547
Reputation: 84687
You have any array of Staff
objects that you filter and then try to return as an array of AssignedStaff
. Staff
and AssignedStaff
do not share any fields except for id
-- which is why you see the id
field populated but not the staff
field.
GraphQL is expecting an array like this:
[ { id, staff } ]
and you are passing it
[ { id, name, speciality } ]
You'll need to modify your resolver to look something like this:
return staff
.filter(s => s.id === booking.AssignedStaff.staffId)
.map(f => ({ id: f.id, staff: f }))
I don't know what (if any) the intended difference between AssignedStaff.id and AssignedStaff.staff.id is so you may need to fiddle with the above code but it should give you a starting point.
Upvotes: 1