2

How could I parse and extract certain values from below JSON

Here is the sample JSON response

{
   "success":true,
   "endpoint":"https://api.abcxyz.com",
   "info":{
      "Guestconnected":134,
      "Guestratio":100000.06963,
      "symbol1":{
         "code":"NY",
         "symbol":"*",
         "name":"newyear",
         "codev":391.78161,
         "symbolAppearsAfter":false,
         "local":true
      },
      "symbol2":{
         "code":"HNY",
         "symbol":"@",
         "name":"HappyNewYear",
         "codev":1000000.0960,
         "symbolAppearsAfter":true,
         "local":false
      },
      "latest":{
         "value":1597509,
         "autovalue":"00099cf8da58a36c08f2ef98650ff6043ddfb",
         "height":474696,
         "time":1499527696
      }
   },
   "Allguest":{
      "all":4,
      "filtered":4,
      "total_invitations":15430,
      "sent_invitations":15430,
      "final_invitations":0
   },
   "Guestlist":[
      {
         "GuestCode":"369AR",
         "all":2,
         "total_invitations":5430,
         "sent_invitations":5430,
         "final_invitations":0,
         "change":0,
         "accounts":0
      },
      {
         "GuestCode":"6POIA96TY",
         "all":2,
         "total_invitations":10000,
         "sent_invitations":10000,
         "final_invitations":0,
         "change":0,
         "accounts":0
      }
   ]
}

My Code is :

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)


type object struct {
    Success bool `json:"success"`
    Endpoint string `json:"endpoint"`
    Allguest struct {
        All int `json:"all"`
        Filtered int `json:"filtered"`
        TotalInvitations int `json:"total_invitations"`
        SentInvitations int `json:"sent_invitations"`
        FinalInvitations int `json:"final_invitations"`
    } `json:"Allguest"`
    Guestlist []struct {
        GuestCode string `json:"GuestCode"`
        All int `json:"all"`
        TotalInvitations int `json:"total_invitations"`
        SentInvitations int `json:"sent_invitations"`
        FinalInvitations int `json:"final_invitations"`
        Change int `json:"change"`
        Accounts int `json:"accounts"`
    } `json:"Guestlist"`
}

func main() {

uri := "https://siteurl.com/api?lists=1"
res, err := http.Get(uri)
fmt.Println(uri)
if err != nil {
fmt.Println("Error:", err)
    log.Fatal(err)
}
defer res.Body.Close()

 var s object
err := json.NewDecoder(res.Body).Decode(&s)
if err != nil {
    log.Fatal(err)
    fmt.Println("Error:", err)
}
fmt.Println(s.Success)
fmt.Println(s.Allguest.TotalInvitations)
for i := 0; i < 6; i++ {
fmt.Println(s.Guestlist[i].TotalInvitations)
)

}

The problem is :

  1. If the response is null it is giving index out of range error how can we avoid this ?

  2. Applying condition if TotalInvitations value is greater than 100 then save in 100.csv else save in others.csv

3 Answers 3

1

If you need only certain entries from JSON you can define a structure with only those fields you are interested in. And if value can be null it is better to declare a pointer in the structure. Please take a look at an example at go playground: https://play.golang.org/p/mEwSXvPg3D

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

Comments

0

use gjson pkg to get value from json document an simple way

example:

package main

import (
    "fmt"

    "github.com/tidwall/gjson"
)

func main() {
    data := []byte(`{
   "success": true,
   "endpoint": "https://api.abcxyz.com",
   "info": {
      "Guestconnected": 134,
      "Guestratio": 100000.06963,
      "symbol1": {
         "code": "NY",
         "symbol": "*",
         "name": "newyear",
         "codev": 391.78161,
         "symbolAppearsAfter": false,
         "local": true
      },
      "symbol2": {
         "code": "HNY",
         "symbol": "@",
         "name": "HappyNewYear",
         "codev": 1000000.096,
         "symbolAppearsAfter": true,
         "local": false
      },
      "latest": {
         "value": 1597509,
         "autovalue": "00099cf8da58a36c08f2ef98650ff6043ddfb",
         "height": 474696,
         "time": 1499527696
      }
   },
   "Allguest": {
      "all": 4,
      "filtered": 4,
      "total_invitations": 15430,
      "sent_invitations": 15430,
      "final_invitations": 0
   },
   "Guestlist": [
      {
         "GuestCode": "369AR",
         "all": 2,
         "total_invitations": 5430,
         "sent_invitations": 5430,
         "final_invitations": 0,
         "change": 0,
         "accounts": 0
      },
      {
         "GuestCode": "6POIA96TY",
         "all": 2,
         "total_invitations": 10000,
         "sent_invitations": 10000,
         "final_invitations": 0,
         "change": 0,
         "accounts": 0
      }
   ]
    }
    `)

    r := gjson.GetBytes(data, "Allguest.total_invitations")
    fmt.Println(r.Value()) // output 15430

    r = gjson.GetBytes(data, "Guestlist.#.total_invitations")
    fmt.Println(r.Value()) // output [5430 10000]
}

Comments

0
  1. If the response is null it is giving index out of range error how can we avoid this?

    Unless I'm misunderstanding you, the response being null shouldn't matter. If you receive 2 Guestlist items, you can only loop over those 2, meaning for i := 0; i < 6; i++ is wrong. Change it to for i := 0; i < len(s.Guestlist); i++ or for i := range s.Guestlist.

  2. Applying condition if TotalInvitations value is greater than 100 then save in 100.csv else save in others.csv

    You will probably want the os package's Create function to create a new file for writing or the OpenFile function, the O_CREATE, O_WRONLY, and O_APPEND file-open flags, and you can pass 0755 as the permission mode (or another set of octal permissions if you want to change access of a file).

    You can then use csvWriter := csv.NewWriter(csvFile) to wrap the resulting io.Writer (assuming there is no error opening the file). From there, you can just write whatever information you require to the file as CSV records. Don't forget to call csvWriter.Flush to flush the output buffer and csvWriter.Error to check whether there was an error flushing the output buffer. Also don't forget to close the file you opened.

8 Comments

@Nancyme You should consider taking a look at the Learning section of the documentation and also explore the core packages. You seem to not understand that the Write method of *csv.Writer only accepts []string, not int. You had the right idea, but you need to determine what data to write to the file and how to convert that data to a slice of strings to do it.
like this TotalInvites := [][]string{{s.Guestlist[i].TotalInvitations}}
@Nancyme You're not converting the integer to a [][]string object by doing that; you're creating a new [][]string object with an integer as the only value, which won't work because int is not a type that is compatible with string. Learn, don't just guess. We're here to help if you encounter trouble and need to ask a question, not to teach you the entire language; I linked resources for learning in my last comment on this answer.
Thanks for the advise, I am trying hard to learn the things but i can't learn the whole language in a single day and i want this ASAP so need some support, I have successfully able to compile & its working as desired with the edited answer, but i am still not sure if its just a workaround or we can modify it to something more professional, I will appreciate if you can take a look and modify accordingly, thanks and i appreciate your support
It's on the right track, but you're going beyond the scope of your original question. Please ask a new question if you need more help and good luck. :)
|

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.