shurcooL/graphql

Help: Keeps saying "slice doesn't exist in any of 1 places to unmarshal

starjasmine opened this issue ยท 4 comments

I constructed an apollo-server following https://www.apollographql.com/docs/apollo-server/getting-started/

and wrote my own test code like below and ran it.

package main

import (
	"context"
	"fmt"

	"github.com/shurcooL/graphql"
)

func main() {
	graphqlEndPoint := "http://localhost:4000/graphql"

	client := graphql.NewClient(graphqlEndPoint, nil)

	var query struct {
		Books struct {
			Title  graphql.String
			Author graphql.String
		}
	}

	err := client.Query(context.Background(), &query, nil)
	if err != nil {
		fmt.Println("Error!")
		fmt.Println(err)
	} else {
		books := query.Books
		title := books.Title
		fmt.Println("Book's title: ", title)
	}

}

But, the output keeps saying

slice doesn't exist in any of 1 places to unmarshal

At the same time, HTTP request and response were exchanged between the server and my test code normally like,

POST /graphql HTTP/1.1
Host: localhost:4000
User-Agent: Go-http-client/1.1
Content-Length: 34
Content-Type: application/json
Accept-Encoding: gzip

{"query":"{books{title,author}}"}
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Content-Length: 151
ETag: W/"97-OQyi1FTc2fXipdwwic9mDqhbuOo"
Date: Wed, 04 Sep 2019 09:22:20 GMT
Connection: keep-alive

{"data":{"books":[{"title":"Harry Potter and the Chamber of Secrets","author":"J.K. Rowling"},{"title":"Jurassic Park","author":"Michael Crichton"}]}}

Did I do something wrong?

Books struct { ... } should be Books []struct { ... } in your query struct. There can be many books, so it needs a slice to unmarshal the JSON array into.

That said, this package should do something better in this situation. Either the error message needs to be improved, or maybe it could unmarshal just the first book and drop the rest.

Edit: Filed #46 for this.

@dmitshur Thanks for your reply. I think your plans look great. Hope it's updated as you mentioned sooner or later. ๐Ÿ˜ƒ By the way, I'm a novice to Golang. So I simply tried your suggestion (like Books []struct { ... }) as it looks. Sorry, but, Golang seems don't support such expression. ๐Ÿ˜ž

The message is like:

/main.go:31:17: books.Title undefined (type []struct { Title graphql.String; Author graphql.String } has no field or method Title)

Oh, after you change Books to be a slice of structs, you need to access each book by iterating over the slice. For example:

books := query.Books
fmt.Printf("There are %d book(s).\n", len(books))
for i, b := range books {
	title := b.Title
	fmt.Printf("Book (index==%d) title: %s\n", i, title)
}

@dmitshur It works wonderfully! Thank you for your help!