1

Hey there just started to transform my python code to Go, but have some issue on the json manipulations... here is my code so far

package test

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
    "time"
)

type Collection struct {
    Contract string
}

type Data struct {
    Activity Activity `json:"activity"`
}

type Activity struct {
    Activities Activities `json:"activities"`
    HasMore    bool       `json:"hasMore"`
}

type Activities []Sale

type Sale struct {
    From             string           `json:"from"`
    From_login       string           `json:"from_login"`
    To               string           `json:"to"`
    To_login         string           `json:"to_login"`
    Transaction_hash string           `json:"transaction_hash"`
    Timestamp        int              `json:"timestamp"`
    Types            string           `json:"type"`
    Price            float32          `json:"price"`
    Quantity         string           `json:"quantity"`
    Nft              Nft              `json:"nft"`
    Attributes       string           `json:"attributes"`
    Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
    Name       string        `json:"name"`
    Thumbnail  string        `json:"thumbnail"`
    Asset_id   string        `json:"asset_id"`
    Collection NftCollection `json:"collection"`
}

type NftCollection struct {
    Avatar    string `json:"avatar"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

type CollectionStruct struct {
    Avatar    string `json:"avatar"`
    Address   string `json:"address"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

func (c Collection) GetSales(filter, types string) []Sale { // déclaration de ma méthode GetSales() liée à ma structure Collection
    client := &http.Client{Timeout: time.Duration(1) * time.Second}

    const url = "https://backend.api.io/query"

    // create a new request using http
    req, err := http.NewRequest("POST", url)
    if err != nil {
        panic(err)
    }

    // set header for the request
    req.Header.Set("Content-Type", "application/json")

    // send request
    res, err := client.Do(req)
    if err != nil {
        panic(err)
    }

    defer res.Body.Close()
    content, err_ := ioutil.ReadAll(res.Body)
    if err_ != nil {
        panic(err_)
    }

    var resultJson Data
    json.Unmarshal(content, &resultJson)
    fmt.Printf("%+v\n", resultJson)
    return resultJson.Activity.Activities.Sale

}

i don't understand why my Sale structure is empty :/ I created all of these structures in order to use Unmarshal so i can loop. I check the way the returned json is structured and copied it i'm sure i missed something but don't know what

EDIT: I think that i have something, actually the array is Activities and not Sale :

type Collection struct {
    Contract string
}

type Data struct {
    Activity Activity `json:"activity"`
}

type Activity struct {
    Activities Activities `json:"activities"`
    HasMore    bool       `json:"hasMore"`
}

type Activities []struct {
    Sale Sale //`json:"sale"`
}

type Sale struct {
    From             string           `json:"from"`
    From_login       string           `json:"from_login"`
    To               string           `json:"to"`
    To_login         string           `json:"to_login"`
    Transaction_hash string           `json:"transaction_hash"`
    Timestamp        int              `json:"timestamp"`
    Types            string           `json:"type"`
    Price            float32          `json:"price"`
    Quantity         string           `json:"quantity"`
    Nft              Nft              `json:"nft"`
    Attributes       string           `json:"attributes"`
    Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
    Name       string        `json:"name"`
    Thumbnail  string        `json:"thumbnail"`
    Asset_id   string        `json:"asset_id"`
    Collection NftCollection `json:"collection"`
}

type NftCollection struct {
    Avatar    string `json:"avatar"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

type CollectionStruct struct {
    Avatar    string `json:"avatar"`
    Address   string `json:"address"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

But this time it returns me this : {Activity:{Activities:[] HasMore:false}} where Activities value should be an array of Nft struct

3
  • maybe the problem is in API or requestBody, ther're many possibilities. Have you tried it with postman? Commented Aug 27, 2022 at 22:48
  • hey @RahmatFathoni actually the returned response is all good, i have issue while trying to save it in order to manipulate easily Commented Aug 28, 2022 at 7:20
  • Also check status code from response, and debug the content to make sure its no error Commented Aug 28, 2022 at 7:31

2 Answers 2

0

Adding to @larsks 's answer, there are more errors that I can see

  1. ioutil.ReadAll already returns a byte array which you can directly use for un-marshalling. json.Unmarshal(content, &resultJson)

  2. Many errors are ignored so execution won't stop if any error is encountered.

I suggest changing the function as follows:

func (c Collection) GetSales(filter, types string) []Sale {
    const url = "https://api.com/"

    req, err := http.NewRequest("POST", url, requestBody)
    if err != nil {
        panic(err)
    }
    
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }

    defer res.Body.Close()
    content, err := ioutil.ReadAll(res.Body)
    if err != nil {
        panic(err)
    }

    var resultJson Data
    err = json.Unmarshal(content, &resultJson)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v\n", resultJson)
    return resultJson.Activity.Activities.Sales
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for you suggestion, i edited the code but i still got an empty array : {Activity:{Activities:{Sale:[]} HasMore:false}}
0

Your code as written won't compile (due to a couple of undefined variables), so it's hard to separate functional problems from syntactic problems.

However, one thing stands out: You're creating an HTTP request with req, err := http.NewRequest(...), but you're never executing the request with a client. See e.g. the documentation, which includes this example:

client := &http.Client{
    CheckRedirect: redirectPolicyFunc,
}

resp, err := client.Get("http://example.com")
// ...

req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

If you use NewRequest to create a request, you must use client.Do(req) to execute it.

2 Comments

Hey thanks for you answer, actually i do use http.DefaultClient.Do(req) I had to crop my code that's why there was many undefined variable and missing lines, i'll try to edit so it can be better understandable
here is how json is structured : { "data": { "activity": { "activities": [ { "from": "", "from_login": "", "to": "", "to_login": "", "transaction_hash": "", "timestamp": 1661644989, "type": "sale", "price": 1.5, "quantity": "-", "nft": { "name": "MadSkullz #2305", "thumbnail": "", "asset_id": "", "collection": {} }, "attributes": "", "collection": {} },

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.