2

I get json response. Which has key pk and it's value as int. I need to convert it as string, what is the easiest way? Here is the example

"pk": 145250410

and i need it to be

"pk": "145250410"

I can not make model, and parse it bacause i don't always know what will my json be like, but i know it will always have pk, so this is how i parse it.

var bdoc interface{}
bson.UnmarshalJSON([]byte(gjson.Get(*str, "user").String()), &bdoc)

The only problem is that i get pk as int not as string.

5
  • strconv.FormatInt? Or are you trying to marshal or unmarshal directly as a string? Commented Apr 27, 2018 at 19:32
  • @JimB My whole json is in *str. I unmarshall json and get map[string]interface{}. Commented Apr 27, 2018 at 19:35
  • It's unclear what you're asking. Please create a minimal reproducible example. Commented Apr 27, 2018 at 19:35
  • Would you have strings in your json like "0000012345"? Commented Apr 27, 2018 at 19:36
  • @Slabgorb It might have like that Commented Apr 27, 2018 at 19:39

1 Answer 1

4
package main

import (
    "encoding/json"

    "fmt"
    "strconv"
)

var jsonData = []byte(`
{
    "user": {
        "media_count": 2043,
        "follower_count": 663,
        "following_count": 1300,
        "geo_media_count": 0,
        "is_business": false,
        "usertags_count": 423,
        "has_chaining": true,
        "is_favorite": false,
        "has_highlight_reels": true,
        "include_direct_blacklist_status": true,
        "pk": 145250410,
        "username": "karahray",
        "full_name": "K Ray \ud83d\udd35",
        "has_anonymous_profile_picture": false,
        "is_private": false,
        "is_verified": false,
        "profile_pic_url": "",
        "profile_pic_id": "1403809308517206571_145250410",
        "biography": "Austinite, oncology dietitian, lover of food, coffee, beer, scenic jogs, traveling, Los Spurs, my Yorkies and LAUGHING! Fitness/food @LGFTatx!",
        "external_url": "",
        "hd_profile_pic_url_info": {
            "height": 1080,
            "url": "",
            "width": 1080
        },
        "hd_profile_pic_versions": [{
            "height": 320,
            "url": "",
            "width": 320
        }, {
            "height": 640,
            "url": "",
            "width": 640
        }], 
        "reel_auto_archive": "on",
        "school": null,
        "has_unseen_besties_media": false,
        "auto_expand_chaining": false
    },
    "status": "ok"
}`)


// custom json unmarshal
type pk string

func (p *pk) UnmarshalJSON(data []byte) error {
    var tmp int
    if err := json.Unmarshal(data, &tmp); err != nil {
        return err
    }
    *p = pk(strconv.Itoa(tmp))
    return nil
}

type jsonModel struct {
    User struct {
        PK pk `json:"pk"`
    } `json:"user"`
}

func main() {
    // using the custom json unmarshal
    jm := &jsonModel{}
    if err := json.Unmarshal(jsonData, jm); err != nil {
        panic(err)
    }

    // doing it as map[string]interface, then finding the key, 
    // then converting - you end up needing TONS of casting 
    everything := map[string]interface{}{}
    if err := json.Unmarshal(jsonData, &everything); err != nil {
        panic(err)
    }

    var userPart interface{}
    userPart, ok := everything["user"]
    if !ok {
        panic("could not find user key")
    }
    userPartMap := userPart.(map[string]interface{})
    var pkInterface interface{}

    if pkInterface, ok = userPartMap["pk"]; !ok {
        panic("could not find pk key")
    }

    // note that json is going to 'guess' float64 here, so we 
    // need to do a lot of shenanigans.
    pkString := strconv.FormatInt(int64(pkInterface.(float64)),10)

    fmt.Printf("%s\n", jm.User.PK)
    fmt.Printf("%s\n", pkString)


}

Output:

145250410

145250410

https://play.golang.org/p/OfHi0ybHJXE

Sign up to request clarification or add additional context in comments.

6 Comments

I dont know what the response will be like, that is why i dont use struct... That is the main problem
As long as the 'pk' key is in the top level of the json, this will work regardless of the remaining structure of the json. In other words, you don't need to unmarshal EVERYTHING at once, you can just unmarshal what you are looking for.
i hope this will help you, my json looks like this: pastebin.com/JgM347zP here you can see that pk is of type int and i need to convert it to type string. That is what i am trying to achieve
this will always have only pk. If i try this fmt.Printf("%s", p.PK) output is: {000012345} And there is no rest of the json.
Ok, edited answer, including your json. Likely someone else could come up with a more efficient way of working with the unstructured version. I was trying to avoid doing things like using reflect. I would still recommend not having a map[string]interface{} running through your program, it just makes things very difficult. One thing to improve this a lot is by using the two-return casting to prevent random panics from bad casting.
|

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.