You can easly grab a json data with a fetch or XMLHTTPRequest and use it. A json data is always represented as a map[string]interface{}. To avoid panic, you must always ensure the data you want has the good type with Type Assertions.
Example with a JSON string
var myjsonstr = `{
"name":"John",
"age":30,
"cars":[ "Ford", "BMW", "Fiat" ]
}`
func main() {
hogosuru.Init()
if j, err := json.Parse(myjsonstr); hogosuru.AssertErr(err) {
extractdata := j.Map()
if arrayincars, ok := extractdata.(map[string]interface{})["cars"].([]interface{}); ok {
if len(arrayincars) > 0 {
//ensure that the first element is a string
if valuestr, ok := arrayincars[0].(string); ok {
fmt.Printf("First Element in cars is %s\n", valuestr)
}
}
}
if arrayincars, ok := extractdata.(map[string]interface{})["boat"].([]string); ok {
if len(arrayincars) > 0 {
fmt.Printf("First Element in boat is %s\n", arrayincars[0])
}
} else {
fmt.Printf("Boat is not present in json\n")
}
}
}
Execute with headless mode
GOOS=js GOARCH=wasm go run jsonwithstring/main.go
Result:
First Element in cars is Ford
Boat is not present in json
There are no channel waiting at the end of the main. We just want execute and stop.
If you inserted the waiting channel, your browser will continue to run and you must hit ctrl+c to stop the run.
Example with a JSON file
The example below use a fetch to retrieve a json file and parse the data. Fetch is a promise and follow the mechanic of promise. This mechanical will be explained in the next guides.
func main() {
hogosuru.Init()
var httpHeaders map[string]interface{} = map[string]interface{}{"Content-Type": "application/json"}
var fetchOpts map[string]interface{} = map[string]interface{}{"method": "GET", "headers": httpHeaders}
//Start promise and wait result
if f, err := fetch.New("https://httpbin.org/get", fetchOpts); hogosuru.AssertErr(err) {
f.Then(func(r response.Response) *promise.Promise {
//when header is ready the function is execute
if status, err := r.Status(); hogosuru.AssertErr(err) {
if status == 200 {
if promiseGetJSONData, err := r.Text(); hogosuru.AssertErr(err) {
//when data is ready the text is get
promiseGetJSONData.Then(func(i interface{}) *promise.Promise {
//we must ensure that the object send is a string like expected
if textstr, ok := i.(string); ok {
if j, err := json.Parse(textstr); hogosuru.AssertErr(err) {
jsonmap := j.Map()
if headers, ok := jsonmap.(map[string]interface{})["headers"]; ok {
if uaheader, ok := headers.(map[string]interface{})["User-Agent"].(string); ok {
fmt.Printf("User-Agent %s\n", uaheader)
}
}
}
}
return nil
}, func(e error) {
fmt.Printf("An error occurs %s\n", err.Error())
})
}
} else {
fmt.Printf("Must return a 200 HTTP Code")
}
}
return nil
}, func(e error) {
fmt.Printf("An error occurs %s\n", err.Error())
})
}
ch := make(chan struct{})
<-ch
}
Start with headless mode:
GOOS=js GOARCH=wasm go run jsonwithstring/main.go
Result:
Thanks to fetch with get the result of get HTTP, Get the text data and parse it with json.
We get the json["headers"]["User-Agent"] data
User-Agent Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/99.0.4844.51 Safari/537.36
The waiting channel is very important here. If you remove it , the fetch is launched in a separated worker and you main will stop immediatly without the fetch has time to finish. The infinite loop will force you to hit ctrl+c to stop. An improved version can be write to send the channel to stop when promise is finished or in error , or with a chained promise.
Using channel with wasm to sync execution is dangerous, not advised, and must be use with precaution. It can create deadlock problems. Always prefer promise to sync.
Factoring Fetch JSON
Of course the fetch example use low level access of promise and fetch. It's verbose but you can control anything.
You can also create some helpers to easily write POST,GET for your apps and the final result will be more friendly.
Here an example of one of my project with factoring fetch: