0

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
}
1
  • The error will show you exactly where the nil pointer dereference happens. Where is that in the code? Commented Feb 27, 2019 at 16:32

1 Answer 1

3

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 :=)

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.