Ana be
Ana be

Reputation: 111

Invalid memory address or nil pointer dereference in golang

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

Answers (1)

retgits
retgits

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

Related Questions