NOT an issue, more a touch of help. Using parameters with gojsonq package
JamieW87 opened this issue · 9 comments
I am trying to build a server that can fetch certain json entries based on a parameter.
So for example if a user enters localhost:8080/store/1 It returns the json entry with the ID 1.
The code i currently have works if i hardcode the id field into the query, but trying to put in parameters i have so far had no luck.
Trying this:
func getGame(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
jq := gojsonq.New().File("./data/games.json")
res := jq.From("games").Where("id", "=", params["id"]).Get()
fmt.Println(res)
}
Suggestions please, before i throw something out the window.
It would be better if you provided full code for reproducing the behaviour. Just using parameter works for me:
package main
import (
"fmt"
"math/rand"
"time"
"github.com/thedevsaddam/gojsonq"
)
const json = `
{
"name":"computers",
"description":"List of computer products",
"prices":[2400, 2100, 1200, 400.87, 89.90, 150.10],
"names":["John Doe", "Jane Doe", "Tom", "Jerry", "Nicolas", "Abby"],
"items":[
{
"id":1,
"name":"MacBook Pro 13 inch retina",
"price":1350
},
{
"id":2,
"name":"MacBook Pro 15 inch retina",
"price":1700
},
{
"id":3,
"name":"Sony VAIO",
"price":1200
},
{
"id":4,
"name":"Fujitsu",
"price":850
},
{
"id":null,
"name":"HP core i3 SSD",
"price":850
}
]
}
`
func main() {
rand.Seed(time.Now().UnixNano())
jq := gojsonq.New().JSONString(json).From("items").WhereEqual("id", rand.Intn(5))
fmt.Printf("%#v\n", jq.Get())
}
go run test.go
[]interface {}{map[string]interface {}{"price":1200, "id":3, "name":"Sony VAIO"}
}go run test.go
[]interface {}{map[string]interface {}{"name":"MacBook Pro 15 inch retina", "pri
ce":1700, "id":2}}
I am trying to build a server that can fetch certain json entries based on a parameter.
So for example if a user enters localhost:8080/store/1 It returns the json entry with the ID 1.The code i currently have works if i hardcode the id field into the query, but trying to put in parameters i have so far had no luck.
Trying this:func getGame(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) jq := gojsonq.New().File("./data/games.json") res := jq.From("games").Where("id", "=", params["id"]).Get() fmt.Println(res) }
Suggestions please, before i throw something out the window.
It seems the id
field is an integer and you are providingparams["id"]
, which returns id as a string.
Try something like this: Where("id", "=", int(params["id"]))
or Where("id", "=", float64(params["id"]))
If not working, provide more information/source code/data structure.
Try convert this way:
i, _ := strconv.Atoi(params["id"])
res := jq.From("games").WhereEqual("id", i).Get()
Using Atoi worked a treat. Thank you for pointing me in the right direction.
My question now has a second phase if you dont mind. It now prints out the json as the screenshot below.
What do i need to use to print it out as per the structs?
games.go:
package models
type Games struct {
Games []Game `json:"games"`
Comments []Comment `json:"comments"`
}
type Comment struct {
User string `json:"user"`
Message string `json:"message"`
DateCreated string `json:"dateCreated"`
Like int `json:"like"`
}
type Game struct {
ID int `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
By string `json:"by"`
Platform string `json:"platform"`
AgeRating string `json:"age_rating"`
Likes int `json:"likes"`
Comment Comment `json:"comments"`
}
games.json
"games":[
{"id": 1,
"title": "Uncharted 4",
"description": "For the first time ever in Uncharted history, drive vehicles during gameplay",
"by": "Sony",
"platform": ["PS4"],
"age_rating": "16",
"likes": 100,
"comments": [{
"user": "bob",
"message": "Cracking game far too much cinematic",
"dateCreated": "2011-01-03",
"like": 6
}, {
"user": "testingPriest",
"message": "Not enough shooting for me,far too easy ",
"dateCreated": "2011-04-02",
"like": 5
}]
},
Define corresponding method (String/0) for your structs.
From the documentation:
Except when printed using the verbs %T and %p, special formatting considerations apply for operands that implement certain interfaces. In order of application:
If the operand is a reflect.Value, the operand is replaced by the concrete value that it holds, and printing continues with the next rule.
If an operand implements the Formatter interface, it will be invoked. Formatter provides fine control of formatting.
If the %v verb is used with the # flag (%#v) and the operand implements the GoStringer interface, that will be invoked.
If the format (which is implicitly %v for Println etc.) is valid for a string (%s %q %v %x %X), the following two rules apply:
If an operand implements the error interface, the Error method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
If an operand implements method String() string, that method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
Sorry i'm showing my inexperience here but how do i do that? I want to return the json as it appears in the json file. Ive tried unmarshalling it etc but that doesnt seem to work with this package.
Ahh, it's seems I didn't understand what format you want to get. Well you can use method Writer to write result to any io.Writer in json format.
If my assumptions still wrong it would be better provide format which do you want to see. I mean exactly content of file or something like that :)
Having a play, Ive now managed to get this output, using MarshalIndent. But the keys are not in the right order, they dont match the order of the original json file above:
Here is the code of the function now
func getGame(w http.ResponseWriter, r *http.Request) {
//Open the json file
jq := gojsonq.New().File("./data/games.json")
params := mux.Vars(r)
//Convert the param string to an int to match the json and so it can be used in the query
idTwo, _ := strconv.Atoi(params["id"])
//Query the json to print out the parameter from the url
res := jq.From("games").Where("id", "=", idTwo).Get()
//json.NewEncoder(w).Encode(res)
//Prints to the console
fmt.Println(res)
//Prints to browser
b, _ := json.MarshalIndent(res, "", "")
w.Write(b)
}