Converting a slice of structs into a single JSON file

Hello all,

I’ve been retooling an app I’m working on to produce JSON instead of sending my templates a slice of structs. I’m marshaling the data, but since there’s many rows in my database, the format of the JSON isn’t coming out right.

Here’s the code pulling the data from PostreSQL and creating an slice of structs for each row:

package model

import (
	"fmt"

	"github.com/nasquam/taskmaster/viewmodel"
)

//PullTasks will print out all the records in the database
func PullTasksJSON() ([]viewmodel.ActionRequest, error) {
	fmt.Println("Start pull tasks")

	rows, err := db.Query(`
		SELECT
			id,
			assignedto,
			requester,
			requestname,
			company,
			priority,
			status,
			completeby
		FROM
			golang.tasks
		WHERE
			owner = $1 AND active = $2`,
		"Steven Aiello", "y")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var results []viewmodel.ActionRequest
	for rows.Next() {
		var result viewmodel.ActionRequest
		err = rows.Scan(
			&result.ID,
			&result.AssignedTo,
			&result.RequestedBy,
			&result.RequestName,
			// for V2 &result.RequestText,
			&result.CompanyName,
			&result.Priority,
			&result.Status,
			// for V2 &result.taskOwner,
			// for V2 &result.requestedOn,
			// for V2 &result.active,
			&result.CompleteBy)
		if err != nil {
			return nil, err
		}

		results = append(results, result)
	}

	return results, nil
}

Here is the code calling the function and “trying” to convert the slice of structs to a single JSON file.

"html/template"
	"net/http"

	"github.com/nasquam/taskmaster/model"
)

type taskmasterJSON struct {
	taskmasterJSONTemplate *template.Template
}

func (h taskmasterJSON) registerRoutes() {

	http.HandleFunc("/taskmasterJSON", h.taskHolderJSON)
	http.HandleFunc("/taskmasterJSON/", h.taskHolderJSON)
}

func (h taskmasterJSON) taskHolderJSON(w http.ResponseWriter, r *http.Request) {

	myResults, _ := model.PullTasksJSON()

	for _, result := range myResults {
		JSON, err := json.MarshalIndent(result, "", "\t")
		if err != nil {
			fmt.Println("error:", err)
		} else {
			w.Header().Set("Content-Type", "application/json")
			w.Write(JSON)
		}
	}
}

Thank you very much

You can marshal myResults directly:

func (h taskmasterJSON) taskHolderJSON(w http.ResponseWriter, r *http.Request) {
	myResults, err := model.PullTasksJSON()
	if err != nil {
		fmt.Println("error:", err)
		http.Error(w, "internal error", http.StatusInternalServerError)
		return
	}
	
	JSON, err := json.MarshalIndent(myResults, "", "\t")
	if err != nil {
		fmt.Println("error:", err)
		http.Error(w, "internal error", http.StatusInternalServerError)
		return
	}
	
	w.Header().Set("Content-Type", "application/json")
	w.Write(JSON)
}

That will produce an array of objects. If you need to change how marshal names things, read the docs at http://godoc.org/encoding/json#Marshal to help you tag the result struct.

1 Like

DOH! Thank you very much.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.