1

This appeared as if it might answer my question, however I am not able to make the output write/save properly to "somefile.json" ( named "deck.json" in my code) no matter what I have tried. My guess is that the form input and the writer are missing each other due to the file being opened/closed at the wrong times, but I honestly do not know. I am attempting to shoehorn this example into a form that allows for a user to input terms and definitions that will save to a JSON file which will be referenced by a JavaScript-powered "flash card" app housed on another page.

Here is the code I have at this moment:

HTML:

<html>
<head>
        <meta charset="utf-8">
        <title>Flashcards for Learning JS</title>
</head>
<body>
   <br>
<form action="/addcard" method="post">
   <input type="text" name="term" placeholder="Term">
   <br>
   <br>
   <input type="text" name="definition" placeholder="Definition">
   <br>
   <br>
   <input type="submit" value="Add Card">
</form>
</body>
</html>

GO:

 package main

import (
    "encoding/json"
    "html/template"
    "net/http"
    "os"
)

type Card struct {
    Term       string `json:"term"`
    Definition string `json:"definition"`
}

func open(w http.ResponseWriter, r *http.Request) {
    t, _ := template.ParseFiles("Form.html")
    t.Execute(w, nil)
}

func addcard(w http.ResponseWriter, r *http.Request) {
    f, err := os.Open("deck.json")
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    card := new(Card)
    card.Term = r.FormValue("term")
    card.Definition = r.FormValue("definition")

    b, err := json.Marshal(card)
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    f.Write(b)
    f.Close()
}

func main() {
    http.HandleFunc("/", open)
    http.ListenAndServe(":8080", nil)
    http.HandleFunc("/addcard", addcard)
}
7
  • Your not checking the error from f.Write, always check errors. Your file is read only. Commented Aug 29, 2016 at 21:55
  • Unfortunately that doesn't appear to be the case unless something is escaping me re: file permissions. The permissions for "deck.json" are currently set to allow for all users to read/write/execute. Commented Aug 29, 2016 at 22:01
  • No, it is the case, check the error from Write. You're opening the file with O_RDONLY: golang.org/pkg/os/#Open Commented Aug 29, 2016 at 22:06
  • Sorry, I'm still misunderstanding, and I'm at a loss as to how to error check Write after searching, but after reading the documentation more thoroughly, I see now that os.Open DOES default to O_RDONLY, but I'm also wondering how or why that would matter if the permissions for the file itself are set to 0666? Is it the way that Go is opening the file that does this only at the moment the code is executed? At any rate, I've amended the line to specify the following: f, err := os.OpenFile("deck.json", os.O_APPEND, 0666) Commented Aug 29, 2016 at 22:25
  • @JimB implemented the error check from go by example for f.Write and didn't turn anything up: gobyexample.com/writing-files Also tried re-specifying f, err := os.OpenFile("deck.json", os.O_RDWR, 0666) to no avail. What am I not getting? Commented Aug 29, 2016 at 22:50

1 Answer 1

1

Changed per recommendations made by @JimB. Fixed handler order, and program successfully concatenates each successive submission as valid JSON to the file in question.

HTML:

<html>
<head>
        <meta charset="utf-8">
        <title>Flashcards for Learning JS</title>
</head>
<body>
   <br>
<form action="/addcard" method="post">
   <input type="text" name="term" placeholder="Term">
   <br>
   <br>
   <input type="text" name="definition" placeholder="Definition">
   <br>
   <br>
   <input type="submit" value="Add Card">
</form>
</body>
</html>

GO:

package main

import (
    "encoding/json"
    "html/template"
    "net/http"
    "os"
)

type Card struct { //defining the data structure for our virtual flashcards
    Term       string `json:"Term"`
    Definition string `json:"Definition"`
}

func open(w http.ResponseWriter, r *http.Request) {
    t, _ := template.ParseFiles("addcard.html")
    t.Execute(w, nil)
}

func addcard(w http.ResponseWriter, r *http.Request) {
    f, err := os.OpenFile("deck.json", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }
    defer f.Close()

    card := new(Card)
    card.Term = r.FormValue("term")
    card.Definition = r.FormValue("definition")

    b, err := json.Marshal(card)
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    f.Write(b)
    f.Close()
}

func main() {
    http.HandleFunc("/addcard", addcard)
    http.HandleFunc("/", open)
    http.ListenAndServe(":8080", nil)

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

Comments

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.