简体   繁体   中英

How to return nested JSON?

I have 3 table in PostgreSQL database.

QUESTIONS table:

| id (int) | text (text)                          |
|----------|--------------------------------------|
| 1        | What is your favorite color?         |
| 2        | What is your favorite football club? |

OPTIONS table:

| id (int) | text (text) |
|----------|-------------|
| 1        | red         |
| 2        | blue        |
| 3        | grey        |
| 4        | green       |
| 5        | brown       |

QUESTIONS_OPTIONS table:

| question_id (int) | option_id (int) |
|-------------------|-----------------|
| 1                 | 1               |
| 1                 | 2               |
| 1                 | 3               |
| 1                 | 4               |
| 1                 | 5               |

In Golang application I create such models:

type Option struct {
    ID   int    `json:"option_id"`
    Text string `json:"option_text"`
}

type Question struct {
    ID int `json:"question_id"`
    Text string `json:"question_text"`
    Options []Option `json:"options"`
}

In controller I have such code:

var GetQuestions = func(responseWriter http.ResponseWriter, request *http.Request) {
    rows, _ := database.DBSQL.Query("SELECT * FROM questions;")
    defer rows.Close()

    var questions []Question

    for rows.Next() {
        var question Question
        var options []Option

        queries, _ := database.DBSQL.Query(`select options.id as option_id, options.text as option_text from questions_options inner join questions on questions_options.question_id = ` + &question.ID + ` inner join options on questions_options.option_id = options.id`)
        queries.Close()

        for queries.Next() {
            var option Option
            if err := queries.Scan(&option.ID, &option.Text); err != nil {
                log.Println(err)
            }
            options = append(options, option)
        }

        if err := rows.Scan(&question.ID, &question.Text, options); err != nil {  // service raise error in this line: sql: expected 2 destination arguments in Scan, not 3
            log.Println(err)
        }

        questions = append(questions, question)
    }
    utils.Response(responseWriter, http.StatusOK, questions)
}

When I try to make GET request to take all questions with all there options service such incorrect result:

[
    {
        "question_id": 0,
        "question_text": "",
        "options": null
    },
    {
        "question_id": 0,
        "question_text": "",
        "options": null
    }
]

Where I make mistake?

You should move queries.Close() to the end of loop, like this:

var GetQuestions = func(responseWriter http.ResponseWriter, request *http.Request) {
    rows, _ := database.DBSQL.Query("SELECT * FROM questions;")
    defer rows.Close()

    var questions []Question

    for rows.Next() {
        var question Question

        if err := rows.Scan(&question.ID, &question.Text); err != nil {
            log.Println(err)
            continue
        }

        queries, _ := database.DBSQL.Query(`select options.id as option_id, options.text as option_text from questions_options inner join questions on questions_options.question_id = $1 inner join options on questions_options.option_id = options.id`, question.ID)

        for queries.Next() {
            var option Option
            if err := queries.Scan(&option.ID, &option.Text); err != nil {
                log.Println(err)
            }
            question.Options = append(question.Options, option)
        }
        queries.Close()

        questions = append(questions, question)
    }
    utils.Response(responseWriter, http.StatusOK, questions)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM