Below is the controller to create new user. I have used it without the code of file upload(placed string instead). It's working perfect. But this code shows below error. I am not getting any specific reason or handled error.
controller
func UserCreate(c *gin.Context) {
// Parse the form data with a higher maxMemory and parseMultipartForm
if err := c.Request.ParseMultipartForm(10 << 20); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to parse form data: " + err.Error(),
})
return
}
// Get data from request body
var body struct {
Username string `form:"username"`
FirstName string `form:"first_name"`
LastName string `form:"last_name"`
Email string `form:"email"`
About string `form:"about"`
U_RoleID uint `form:"role_id"`
IsActive bool `form:"is_active"`
Password string `form:"password"`
}
if err := c.Bind(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to read request body: " + err.Error(),
})
return
}
// Get the file of avatar
file, err := c.FormFile("avatar")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to upload image",
})
return
}
//Save the avatar file
extension := filepath.Ext(file.Filename)
timestamp := time.Now().Unix()
NewFileName := fmt.Sprintf("%s_%d%s", body.Username, timestamp, extension)
if err := c.SaveUploadedFile(file, "/../assets/uploads/"+NewFileName).Error; err != nil {
// Log the error
fmt.Println("Error saving avatar file:", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to save avatar file",
})
return
}
//Hash password with bcrypt
hash, err := bcrypt.GenerateFromPassword([]byte(body.Password), 10)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to hash password",
})
return
}
//create a User
user := models.User{Username: body.Username, FirstName: body.FirstName, LastName: body.LastName, Email: body.Email, About: body.About, Avatar: NewFileName, U_RoleID: body.U_RoleID, IsActive: body.IsActive, Password: string(hash)}
result := initializers.DB.Create(&user)
if result.Error != nil {
// Log the error
fmt.Println("Error creating user:", result.Error)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to create new user",
})
return
}
//return User data
c.JSON(http.StatusOK, gin.H{
"User": user,
})
}
Error:
runtime error: invalid memory address or nil pointer dereference
LoadEnvVariables
package initializers
import (
"fmt"
"github.com/joho/godotenv"
)
func LoadEnvVariables() {
err := godotenv.Load(".env")
if err != nil {
fmt.Println("Error loading .env file")
}
}
Initializers package:
package initializers
import (
"log"
"os"
"github.com/joho/godotenv"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
func ConnectToDB() *gorm.DB {
//Load .env file
err := godotenv.Load(".env")
if err != nil {
log.Fatal("Error reading .env file: ", err)
}
//Get Environment Variables
dbUser := os.Getenv("DB_USER")
dbPassword := os.Getenv("DB_PASSWORD")
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
dbName := os.Getenv("DB_NAME")
//MySQL connection string
dsn := dbUser + ":" + dbPassword + "@tcp(" + dbHost + ":" + dbPort + ")/" + dbName + "?charset=utf8mb4&parseTime=True&loc=Local"
// Connect to MySQL database
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err.Error())
}
// Assign the database instance to the global variable
DB = db
return DB
}
func CloseDB() error {
if DB != nil {
sqlDB, err := DB.DB()
if err != nil {
return err
}
sqlDB.Close()
}
return nil
}
Below is the model related to it:
type User struct {
gorm.Model
Username string `gorm:"type:varchar(64);unique"`
FirstName string `gorm:"type:varchar(64)"`
LastName string `gorm:"type:varchar(64)"`
Email string `gorm:"type:varchar(128);unique"`
About string `gorm:"type:text"`
Avatar string `gorm:"type:text"`
U_RoleID uint `gorm:"index"`
IsActive bool
Password string `gorm:"type:varchar(255)"`
}
Just for easy to test, below is the route
r.POST("/api/user", controllers.UserCreate)
Used tools (Gin, Gorm, Bcrypt, MySQL)
You do have an issue at here
when there isn't an error returned from
SaveUploadedFile(which means got nil), then you won't able to accessErrorfrom nil object.change this into
Also please note, Error is a method