When uploading a file through my frontend (React), Go is reading the csv file and then sending the data in a structured format in a JSON response.
The JSON response:
{
"Success": true,
"labels": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"data": [
{
"label": "",
"data": null,
"borderColor": "",
"backgroundColor": ""
},
{
"label": "Kyle",
"data": [
"1517",
"1689",
"1719",
"1591",
"1490",
"1310",
"1533",
"1500",
"1400",
"1300",
"1600",
"1800"
],
"borderColor": "#f6ff00",
"backgroundColor": "#f6ff00"
},
{
"label": "Mickey",
"data": [
"3000",
"3100",
"3200",
"3000",
"3500",
"4000",
"3700",
"3500",
"3000",
"4000",
"5000",
"4000"
],
"borderColor": "#ff0000",
"backgroundColor": "#ff0000"
},
{
"label": "Donald",
"data": [
"2500",
"2000",
"2800",
"3000",
"3100",
"2900",
"2800",
"3000",
"3200",
"3400",
"3500",
"3800"
],
"borderColor": "#001eff",
"backgroundColor": "#001eff"
}
]
}
You see the problem is this line under data:
{"label":"","data":null,"borderColor":"","backgroundColor":""}
I do not know why this is being added in by Go
The CSV file:
,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
Kyle,1517,1689,1719,1591,1490,1310,1533,1500,1400,1300,1600,1800
Mickey,3000,3100,3200,3000,3500,4000,3700,3500,3000,4000,5000,4000
Donald,2500,2000,2800,3000,3100,2900,2800,3000,3200,3400,3500,3800
func RouteUpload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
r.ParseMultipartForm(16 * 1024 * 1024) // 16MB
file, handler, err := r.FormFile("file")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
defer file.Close()
// Create an empty file on filesystem
f, err := os.OpenFile(filepath.Join("uploads", handler.Filename), os.O_WRONLY|os.O_CREATE, 0666)
defer f.Close()
// Copy the file to the images directory
io.Copy(f, file)
w.Header().Set("Content-Type", "application/json")
type MyData struct {
Label string `json:"label"`
Data []string `json:"data"`
BorderColor string `json:"borderColor"`
BackgroundColor string `json:"backgroundColor"`
}
type MyFile struct {
Success bool `json:"Success"`
Labels []string `json:"labels"`
Data []MyData `json:"data"`
}
var myData MyData
var myFile MyFile
path := "uploads/" handler.Filename
// open file
fi, err := os.Open(path)
if err != nil {
log.Fatal(err)
}
// remember to close the file at the end of the program
defer f.Close()
// read csv values using csv.Reader
csvReader := csv.NewReader(fi)
data, err := csvReader.ReadAll()
if err != nil {
fmt.Println(err)
}
colors := []string{"#00ff12", "#f6ff00", "#ff0000", "#001eff", "#ea00ff", "#ff9600"}
for i, line := range data {
if i == 0 {
for j, field := range line {
if j == 0 {
} else {
myFile.Labels = append(myFile.Labels, field)
}
}
} else {
fmt.Println(line)
for j, field := range line {
if j == 0 {
myData.Label = field
} else {
myData.Data = append(myData.Data, field)
}
}
myData.BorderColor = colors[i]
myData.BackgroundColor = colors[i]
}
myFile.Data = append(myFile.Data, myData)
myData.Data = []string{}
}
myFile.Success = true
// Marshal into JSON
responseJson, err := json.Marshal(myFile)
if err != nil {
fmt.Println(err)
}
// Send success response to user in JSON
fmt.Fprintf(w, "%s\n", responseJson)
}
CodePudding user response:
You are treating the first line from the CSV file differently than the others because of the if i==0 {...} else {...}
, but after that you are always appending to myFile.Data
- so for i==0, the empty myData
will be appended. Try moving this append into the else
block.
Some other suggestions: if ... else
is actually discouraged in Go (see https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88). So for the if i==0
, you could avoid the else
by using continue
after the for
loop - then you could move the code out of the else
block. Also, the if j==0 {/*do nothing*/} else {/*do something*/}
should of course be if j!=0 {/*do something*/}
.