Reputation: 111
I'm new to go lang, I loved it so far but I came across this problem when ever I run the application :
invalid memory address or nil pointer dereference
What should I do to fix the problem?
Here is the main file syntax.go
:
package main
import (
"blog/models"
"fmt"
"net/http"
)
func main() {
models.DbConn()
http.HandleFunc("/books", postsIndex)
http.ListenAndServe(":3000", nil)
}
func postsIndex(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, http.StatusText(405), 405)
return
}
bks, err := models.AllPosts()
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
for _, bk := range bks {
fmt.Fprintf(w, "%s, %s", bk.Title, bk.Description)
}
}
and this the database connection db.go
:
package models
import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
var db *sql.DB
func DbConn() {
db, err := sql.Open("mysql","root:@/posts")
if err != nil {
log.Fatal(err)
}else {
fmt.Printf("this is working")
}
defer db.Close()
}
and this the file to get the posts posts.go
:
package models
type Post struct {
Title string
Description string
}
func AllPosts() ([]*Post, error) {
rows, err := db.Query("SELECT * FROM posts")
if err != nil {
return nil, err
}
defer rows.Close()
bks := make([]*Post, 0)
for rows.Next() {
bk := new(Post)
err := rows.Scan(&bk.Title, &bk.Description )
if err != nil {
return nil, err
}
bks = append(bks, bk)
}
if err = rows.Err(); err != nil {
return nil, err
}
return bks, nil
}
Upvotes: 0
Views: 2516
Reputation: 1406
If you look at the console where the error is shown, I guess it'll show something like posts.go:9
. On that line, you're trying to execute a database query but at that point in time, the connection to the database has already been closed.
In your db.go
you have the line
db, err := sql.Open("mysql","root:@/posts")
That line creates two variables for the scope of the function and assigns the values to it. By the time the function finishes, there is nothing left that uses the scoped variable db
so the connection is closed. Because you've used the :=
new variables have been created and you haven't assigned it to the var db *sql.DB
.
As a quick fix, you can change the first part of the DbConn method to
var err error
db, err = sql.Open("mysql", "root@/posts")
I've added a line for a new variable of type error and the assign now assigns the values to existing variables as opposed to creating new ones (=
vs :=
)
Upvotes: 3