> For the complete documentation index, see [llms.txt](https://hogosuru.v-ip.fr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hogosuru.v-ip.fr/guides/load-and-parse-a-json-data.md).

# Load and parse a JSON data

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
```

{% hint style="info" %}
There are no channel waiting at the end of the main. We just want execute and stop.&#x20;

If you inserted the waiting channel, your browser will continue to run and you must hit ctrl+c to stop the run.
{% endhint %}

## 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

}
```

&#x20;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
```

{% hint style="info" %}
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.
{% endhint %}

## Factoring Fetch JSON

Of course the fetch example use low level access of promise and fetch. It's verbose but you can control anything.&#x20;

You can also create some helpers to easily write POST,GET for your apps and the final result will be more friendly.&#x20;

Here an example of one of my project with factoring fetch:

```
dataPost := url.Values{}
dataPost.Set("username", username)
PostHTTP("app/setusername", dataPost, func(result string) {

}, func(e error) {

})
```
