0

I'm working on a web app using Go, JavaScript ans PostgreSQL.

I don't have any problem to link my Go program with the database. But I've some problems with JavaScript.

Here's my Go code which connect to my DB and return a random element of my table when I call localhost:8080:

type Quote struct {
    ID     int
    Phrase string
    Author string
}

var db *sql.DB



func init() {
    var err error
    db, err = sql.Open("postgres", "postgres://gauthier:password@localhost/quotes?sslmode=disable")
    if err != nil {
        panic(err)
    }

    if err = db.Ping(); err != nil {
        panic(err)
    }
    fmt.Println("You connected to your database")
}

func getQuotes(w http.ResponseWriter, r *http.Request) {
    if r.Method != "GET" {
        http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
        return
    }
    rows, err := db.Query("SELECT id, phrase, author FROM citations ORDER BY RANDOM() LIMIT 1;")
    if err != nil {
        http.Error(w, http.StatusText(500), 500)
        return
    }
    defer rows.Close()
    quotations := make([]Quote, 0)
    for rows.Next() {
        qt := Quote{}
        err := rows.Scan(&qt.ID, &qt.Phrase, &qt.Author)
        if err != nil {
            panic(err)
        }
        quotations = append(quotations, qt)
    }
    if err = rows.Err(); err != nil {
        panic(err)
    }

    for _, qt := range quotations {
        payload, _ := json.Marshal(qt)
        w.Header().Add("Content-Type", "application/json")
        w.Write(payload)
    }
}

func main() {
    http.HandleFunc("/", getQuotes)
    http.ListenAndServe(":8080", nil)
}

When I run this program and use curl -i localhost:8080, it returns me what I expect, a random quote from my DB

`gauthier@gauthier-Latitude-7280:~/gocode/sprint0$ curl -i localhost:8080
 HTTP/1.1 200 OK
 Content-Type: application/json
 Date: Thu, 30 Aug 2018 12:28:00 GMT
 Content-Length: 116

 {"ID":7,"Phrase":"I've never had a problem with drugs. I've had problems with the police","Author":"Keith Richards"}`

Now when I try to make the same request but with JavaScript instead of curl with that little script:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Random quote</title>
  </head>
  <body>
    <script type="text/javascript" language="javascript">
      function getQuotations() {
         httpRequest= new XMLHttpRequest();
         httpRequest.onreadystatechange = function() {
             alertContents(httpRequest)
         };
         httpRequest.open("GET", "http://localhost:8080", true);
      }

      function alertContents(httpRequest) {
          console.log("http status: "+httpRequest.status);
          console.log("http response: "+httpRequest.responseText);
      }
    </script>
    <button onclick="getQuotations()">Click here for a quotation</button>
  </body>
</html>

When I click on the button and open the Chromium's console I get:

http status: 0            hello.html:18 
http response:            hello.html:19

Can someone help me?

kostix
  • 51,517
  • 14
  • 93
  • 176
G.D
  • 802
  • 2
  • 7
  • 15
  • `onreadystatechange` fires when, well, the "ready state" changes - not necessarily just when the request finishes. The MDN docs for `onreadystatechange` contain a good example of how to use it correctly (i.e. checking that `readyState==4`): https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/onreadystatechange – Adrian Aug 30 '18 at 12:53
  • 1
    Look at the request (click on it) in the network pane of Chromium's dev tools - is anything returned? – Omortis Aug 30 '18 at 12:53
  • 1
    Look at the Network tab in Chromium's Developer Tools and see if there are any errors; you're likely facing an error regarding "Access-Control-Allow-Origin". See [Access-Control-Allow-Origin error sending a jQuery Post to Google API's](https://stackoverflow.com/q/6114436) and [Basic AJAX request gets "No 'Access-Control-Allow-Origin' header is present on the requested resource" error](https://stackoverflow.com/q/35304817) for more information. – Heretic Monkey Aug 30 '18 at 12:53

2 Answers2

0

Try using you XMLHttpRequest a little differently so that you are using the load event:

 httpRequest= new XMLHttpRequest();
  httpRequest.load= function() {
             alertContents(this.responseText)
  };
  httpRequest.open("GET", "http://localhost:8080", true);
  httpRequest.send();
Shai Aharoni
  • 1,955
  • 13
  • 25
  • I replace my code by yours and it returns me `Failed to load http://localhost:8080/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.` – G.D Aug 30 '18 at 13:11
  • Javascript prevents you from viewing/loading content from an origin other than the app one's itself - so if you make your goApp serve your page at localhost:8080, it will work – billdoor Aug 30 '18 at 13:37
  • Yes but my Go App and my views aren't on the same machine and I don't how Go can serve a file which is on the same network but not on the same machine – G.D Aug 30 '18 at 14:29
0

I feel like this could be simplified using fetch, if you're comfortable with Promises. You don't have to deal with readystatechange and status codes, etc. Here's an example.

function getQuotations() {
  return fetch('http://localhost:8080')
    .then(response => response.json())
    .then(alertContents)
    .catch(console.error);
}

function alertContents(contents) {
  console.log(contents);
  alert(`"${contents.Phrase}" ~${contents.Author}`);
}
kamoroso94
  • 1,713
  • 1
  • 16
  • 19