How to cast into a type in GraphQL - graphql

For example, through GitHub explorer one can retrieve different types of time line items for a pull request (in this example PULL_REQUEST_COMMIT and PULL_REQUEST_REVIEW):
{
repository(name: "react", owner: "facebook") {
pullRequests(last: 10) {
nodes {
number
timelineItems(last: 10, itemTypes: [PULL_REQUEST_COMMIT, PULL_REQUEST_REVIEW]) {
nodes {
__typename
}
}
}
}
}
}
How can I now access different fields of the types PullRequestEvent or PullRequestReviewEvent? In other words, is there a cast or an if-then-else in GraphQL?

nodes returns an array of PullRequestTimelineItems and a PullRequestTimelineItemsis a GraphQL union type. You can use the ...on notation to query for fields of a specific member in the union type:
{
repository(name: "react", owner: "facebook") {
pullRequests(last: 10) {
nodes {
number
timelineItems(last: 10, itemTypes: [PULL_REQUEST_COMMIT, PULL_REQUEST_REVIEW]) {
nodes {
...on PullRequestReview {
body
}
...on PullRequestCommit {
url
}
}
}
}
}
}
}

Related

Apollo cache update is not reflected on paginated query

I have two components, one of the components creates new items, the other one displays them using an "infinite scroll list". These two components do not have a parent/child relationship and they're not rendered at the same time (they're on different "pages").
I've followed these docs and included the modified object in the mutation of my first component. And I can see the new object in the Apollo cache using dev tools. (Car:<some UUID> gets added in the cache after the mutation runs)
My paginated component is configured with relay style pagination, and the pagination works fine, but when I add a new item it doesn't appear in the list until I refresh the page.
My InMemoryCache looks like this:
...
typePolicies: {
// paginated results
Query: {
fields: {
cars: relayStylePagination()
}
},
CarsResult: {
fields: {
edges: {
// Concatenate the incoming list items with
// the existing list items.
merge(existing = [], incoming) {
return [...existing, ...incoming]
}
}
}
},
PageInfo: {
fields: {
endCursor: {
merge(existing, incoming) {
return incoming
}
}
}
}
}
The mutation looks like this:
${CAR_SUMMARY_FRAGMENT}
mutation CreateCar($name: String!) {
createCar(
input: {
name: $name
}
) {
...CarSummary
}
}
The CreateCar return type is Car
Then my paginated query:
query CarsPaginated($after: Cursor) {
cars(
page: { first: 25, after: $after }
orderBy: { field: CREATE_TIME, direction: DESC }
) {
edges {
node {
...CarSummary
}
}
totalCount
pageInfo {
hasNextPage
endCursor
}
}
}
The CarsPaginated return type is CarsResult:
type CarsResult {
edges: [CarEdge]
pageInfo: PageInfo!
totalCount: Int!
}
type CarEdge {
node: Car
cursor: Cursor!
}
Ideally, I'd like the new item to show up at the top of my items list on the other component.
I've tried to use the "refetchQueries" attribute but the paginated query is not active since the list component is not rendered at that time.
Maybe there's something I need to do in the typePolicies?

Attempting to query with graphql where id is

I need to get a query using graphql in strapi/gatsby where id is {id}.
According to the documentation found here you query all like so:
{
allStrapiArticle {
edges {
node {
id
title
content
}
}
}
}
This works and I'm able to query however I'd like to get only one Article where id is {id};
I have tried:
{
allStrapiArticle(id: "4") {
edges {
node {
id
title
content
}
}
}
}
And also:
{
allStrapiArticle {
edges {
node(id: "4") {
id
title
content
}
}
}
}
Both of the above give me an error. Any idea how I can achieve this?
Use:
{
allStrapiArticle(filter: {id: {eq: "4" }}) {
edges {
node {
id
title
content
}
}
}
}
elemMatch filter might be useful for your use case as well.
Check the localhost:8000/___graphql playground to test your queries and filters.
More references:
https://www.gatsbyjs.com/docs/query-filters/
https://www.gatsbyjs.com/docs/graphql-reference/

Get array of repositoryOwner from GitHub GraphQL

I have this query:
query {
repositoryOwner(login: "jcubic") {
repositories(first: 20, orderBy: {field: STARGAZERS, direction: DESC}, privacy: PUBLIC) {
edges {
repository:node {
name
stargazers {
totalCount
}
}
}
}
}
}
is it possible to get multiple users intead of single one?
With help from, I was able to create query using IDs (they are from me and linus torvalds):
{
nodes(ids: ["MDQ6VXNlcjI4MDI0MQ==", "MDQ6VXNlcjEwMjQwMjU="]) {
... on User {
name
login
}
... on RepositoryOwner {
repositories(first: 20, orderBy: {field: STARGAZERS, direction: DESC}, privacy: PUBLIC) {
edges {
repository: node {
name
stargazers {
totalCount
}
}
}
}
}
}
}

Github GraphQL API v4 Query on CommitAuthor

I am trying to run the following query on Githubs GraphQL api:
{
user(login: "davekaj") {
id
repositories(first: 10, orderBy: {field: NAME, direction: ASC}) {
nodes {
ref(qualifiedName: "master") {
target {
... on Commit {
history(first: 15, author: "WHAT DO I PUT HERE") {
totalCount
nodes {
additions
author {
name
user {
id
}
}
committedDate
deletions
}
}
}
}
}
}
}
}
}
It wants me to filter on a CommitAuthor for history(author: ). I tried passing my username, or my unique user ID, but it doesn't work. I am essentially passing it a string, but it wants the type CommitAuthor. How do I pass a CommitAuthor value?
It isn't clear to me, and I searched through the docs and the schema and I couldn't find anything.
Please help!
Ah, so the answer is actually very simple once I looked at the graphql documentation (rather than just the github documentation). CommitAuthor is an input type, which is described here https://graphql.org/graphql-js/mutations-and-input-types/.
The result is you pass an object of CommitAuthor. In this case I just have to pass the id, which looks like this: author: {id: "MDQ6VXNlcjIyNDE3Mzgy"}
See the completed code below.
{
user(login: "davekaj") {
id
repositories(first: 10, orderBy: {field: NAME, direction: ASC}) {
nodes {
ref(qualifiedName: "master") {
target {
... on Commit {
history(first: 15, author: {id: "MDQ6VXNlcjIyNDE3Mzgy"}) {
totalCount
nodes {
additions
author {
name
user {
id
}
}
committedDate
deletions
}
}
}
}
}
}
}
}
}

GraphQL filters in GatsbyJS

I'm having trouble understanding how to write filters for GraphQL queries in GatsbyJS.
This works:
filter: { contentType: { in: ["post", "page"] }
I basically need the reverse of that, like:
filter: { "post" in: { contentTypes } } // where contentTypes is array
That doesn't work because "NAME is expected" (where "post" is in my example).
After going through GatsbyJS docs I found this:
elemMatch: short for element match, this indicates that the field you are filtering will return an array of elements, on which you can apply a filter using the previous operators
filter:{
packageJson:{
dependencies:{
elemMatch:{
name:{
eq:"chokidar"
}
}
}
}
}
Great! That's what I need! So I try that, and I get:
error GraphQL Error Field "elemMatch" is not defined by type markdownRemarkConnectionFrontmatterTagsQueryList_2.
Keywords defined in markdownRemarkConnectionFrontmatterTagsQueryList_2 are:
eq: string | null;
ne: string | null;
regex: string | null;
glob: string | null;
in: Array | null;
Why am I limited to these keywords when more keywords such as elemMatch are mentioned in docs? Why am I not allowed to use the filter structure "element in: { array }"?
How can I create this filter?
Filter by value in an array
Let's say you have a markdown blog with categories as an array of string, you can filter posts with "historical" in categories like this:
{
allMarkdownRemark(filter:{
frontmatter:{
categories: {
in: ["historical"]
}
}
}) {
edges {
node {
id
frontmatter {
categories
}
}
}
}
}
You can try this query out in any of the graphiq blocks in Gatsby.js docs.
ElemMatch
I think elemMatch is only 'turned on' for fields with array of objects; something like comments: [{ id: "1", content: "" }, { id: "2", content: ""}]. This way, you can apply further filters on the fields of each comment:
comments: { elemMatch: { id: { eq: "1" } } }
Here's an example you can try out in the graphiq blocks in gatsby docs:
// only show plugins which have "#babel/runtime" as a dependency
{
allSitePlugin (filter:{
packageJson:{
dependencies: {
elemMatch: {
name: {
eq: "#babel/runtime"
}
}
}
}
}) {
edges {
node {
name
version
packageJson {
dependencies {
name
}
}
}
}
}
}

Resources