#Parsing a JSON file and using its values within a struct?

32 messages · Page 1 of 1 (latest)

weary bobcat
#

Current code:

package main

import (
    "bufio"
    "encoding/json"
    "fmt"
    "log"
    "os"
)

/*
Prompt: Parse JSON

Task: Write a program that reads a JSON string representing a list
of people (with fields for name and age) and parses it into a slice of structs.
Then, print out the names and ages of all people in the list.

STATUS: PENDING
*/

func check(err error) error {
    if err != nil {
        // Throw error if the file is NULL
        log.Fatal(err)
    }
    return err
}

func main() {
    fmt.Println("This is a JSON parser")
    // Read entire file at once
    content, err := os.ReadFile("read.json")
    check(err)

    // Print content
    fmt.Println(string(content))

    // Go over the document word by word
    file, err2 := os.Open("read.json")
    check(err2)

    scan := bufio.NewScanner(file)
    scan.Split(bufio.ScanWords)

    // Parse JSON into a struct

    // JSON decoder
    parser := json.NewDecoder(file)
    var person people

    err = parser.Decode(&person)
    if err != nil {
        // WARNING
        log.Fatalf("Failed to decode JSON: %s", err)
    }

    // reflect --> It enables you to examine the type and value of variables dynamically.

    fmt.Printf("Name: %s\n", person.name)
    fmt.Printf("Age: %d\n", person.age)
    fmt.Printf("City: %s\n", person.city)

    file.Close()
}

// Struct declaration
type people struct {
    name string
    age  uint8
    city string
}

Hi, so I'm trying to use this fairly easy JSON parser, that I don't really fully understand myself even though I wrote it, to take a small JSON file, show it on screen and then print its values in a nicer way, I got to print it but the end result is like this:

This is a JSON parser
{
  "name": "Alice",
  "age": 30,
  "city": "New York"
}
  
Name: 
Age: 0
City: 

How can I fix this? anything I might be missing? If there is any tutorial that explains how to do this task properly, please let me know

#

On the other hand, at the point where I left the WARNING comment, it prompts me this at VSCode.
struct type 'exercises/JSON_parser.people' doesn't have any exported fields, nor custom marshaling (SA9005)
Don't really understand that, should i put the struct before the main function or something?

lofty bramble
weary bobcat
#

now i got it exported, yet i guess i need a way to assign the values from the json to the actual struct?

    // JSON decoder
    parser := json.NewDecoder(file)

    var person people = people{}

    err = parser.Decode(&file)
    if err != nil {

        log.Fatalf("Failed to decode JSON: %s", err)
    }

    // reflect --> It enables you to examine the type and value of variables dynamically.

    fmt.Printf("Name: %s\n", person.name)
    fmt.Printf("Age: %d\n", person.age)
    fmt.Printf("City: %s\n", person.city)

    file.Close()
}

// Struct declaration
type people struct {
    name string
    age  uint8
    city string
}
lofty bramble
#

they are still not exported

#

exported fields start with a capital letter, which determines if they are accessible to other packages or not

weary bobcat
#

oh ok

#

i did a test run with directly written values and it worked! yet i need to pass the values from the json

#

i'm quite lost honestly, do i need the marshall/unmarshall thing by any means?

lofty bramble
#

im not sure what the question is

weary bobcat
#

like, i got the json file output alone, yet i don't get how should i pass the json values into the struct, so i can display its values

lofty bramble
#

can you show your current code?

weary bobcat
#

sure

lofty bramble
#

the only issue you have is that you're scanning the file twice

weary bobcat
#
package main

import (
    "bufio"
    "encoding/json"
    "fmt"
    "log"
    "os"
)

func check(err error) error {
    if err != nil {
        // Throw error if the file is NULL
        log.Fatal(err)
    }
    return err
}

func main() {
    fmt.Println("This is a JSON parser")
    // Read entire file at once
    content, err := os.ReadFile("read.json")
    check(err)

    // Print content
    fmt.Println(string(content))

    // Go over the document word by word
    file, err2 := os.Open("read.json")
    check(err2)

    scan := bufio.NewScanner(file)
    scan.Split(bufio.ScanWords)

    // Parse JSON into a struct

    // JSON decoder
    parser := json.NewDecoder(file)

    //var person people = people{}
    /*
        p := people{
            Name: "Kaneda",
            Age:  30,
            City: "Tokyo",
        }
    */
    err = parser.Decode(&file)
    if err != nil {

        log.Fatalf("Failed to decode JSON: %s", err)
    }

    // reflect --> It enables you to examine the type and value of variables dynamically.

    fmt.Printf("Name: %s\n", p.Name)
    fmt.Printf("Age: %d\n", p.Age)
    fmt.Printf("City: %s\n", p.City)

    file.Close()
}

// Struct declaration
type people struct {
    Name string
    Age  uint8
    City string
}

lofty bramble
#

before you call json.NewDecoder(file) after reading it already, you should use file.Seek(0)

weary bobcat
#

it returns and error, i changed it to file.Seek(4,0) just for the sake of trying and it returned
Failed to decode JSON: json: cannot unmarshal string into Go value of type os.File exit status 1

#

that's what i meant with the marshall/unmarshall thing

#

with a single 0 it just said not enough arguments

lofty bramble
#

you need to call Decode(&person)

#

you are trying to decode it into a *os.File instead of your people struct

weary bobcat
#

ok, tried that, but it returns Failed to decode JSON: json: cannot unmarshal string into Go value of type main.people exit status 1 again, im now using decode over &person

lofty bramble
#

can you share the contents of the file again?

#

it seems your seek(4) is causing the issue now

weary bobcat
#

sure

#
{
  "name": "Tetsuo",
  "age": 16,
  "city": "Neo Tokyo"
}
  
lofty bramble
#

the 4th character is " so its trying to read "name"... into the struct

#

which makes sense based on the error

weary bobcat
#

removing the file.Seek thing worked

#

now it works

lofty bramble
#

👍

weary bobcat
#

thanks!