2

I am new to go and mongo so I created a struct user and another struct prompt having a data multiple values and one of them is a creator field with data type as user struct. what I want is to fetch data from prompt collection and then populate the creator field with the userData from users collection

This is my user model:

type User struct {
    Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
    Email string `json:"email,omitempty" validate:"required"`
    UserName string `json:"username,omitempty" validate:"required"`
    Image string `json:"image,omitempty"`
}

This is my prompt model:

type Prompts struct{
    Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
    Creator User `json:"creator,omitempty" bson:"creator,omitempty" validate:"required"`
    Prompt string `json:"prompt,omitempty" validate:"required"`
    Tag string `json:"tag,omitempty" validate:"required"`
}

this is my getprompt controller code

func GetAllPrompts(c *fiber.Ctx) error {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    var prompts []models.Prompts
    defer cancel()

    result, err := promptCollection.Find(ctx, bson.M{})

    if err != nil {
        return c.Status(http.StatusInternalServerError).JSON(responses.UserResponse{
                    Status: http.StatusInternalServerError, 
                    Message: "error",
                    Data: &fiber.Map{"data": err.Error()
                }})                          
    }

    defer result.Close(ctx)

    for result.Next(ctx) {
        var singlePrompt models.Prompts
        if err = result.Decode(&singlePrompt); err != nil {
            return c.Status(http.StatusInternalServerError).JSON(responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &fiber.Map{"data": err.Error()}})
        }

        var creatorUser models.User
        fmt.Println(singlePrompt.Creator)
        if err := userCollection.FindOne(ctx, bson.M{"_id": singlePrompt.Creator}).Decode(&creatorUser); err != nil {
            return c.Status(http.StatusInternalServerError).JSON(responses.UserResponse{
                Status:  http.StatusInternalServerError,
                Message: "error",
                Data:    &fiber.Map{"data": err.Error()},
            })
        }
        singlePrompt.Creator = creatorUser
        fmt.Println(singlePrompt.Creator)

        prompts = append(prompts, singlePrompt)
    }

    return c.Status(http.StatusOK).JSON(responses.UserResponse{
              Status: http.StatusOK,
              Message: "success", 
              Data: &fiber.Map{"data": prompts}})
}

Here is the modified Prompt Model

type Prompts struct{
    Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
    Creator primitive.ObjectID `json:"creator,omitempty" bson:"creator,omitempty"`
    CreatorUser User `json:"creatorUser,omitempty" bson:"-"`
    Prompt string `json:"prompt,omitempty" validate:"required"`
    Tag string `json:"tag,omitempty" validate:"required"`
}

Here is the response from the API:

{
"status": 200,
"message": "success",
"data": {
  "data": [
            {
              "id": "64eb3acd141064383731f637",
              "creator": "64eb379c0b99ca594e7d5d43",
              "creatorUser": {
                              "id": "64eb379c0b99ca594e7d5d43",
                              "email": "ec20085@glbitm.ac.in",
                              "username": "aakashraj",
                              "image": "https://lh3.googleusercontent.com/a/AAcHTtdbzOqoLcuI5jorkg_YOrJRroHrI6e0FKDzFbjUbYgvGQ=s96-c"
                              },
                "prompt": "Hi this is another user",
                "tag": "#user #web"
              },
            ]
      }
}
Aakash Raj
  • 21
  • 2
  • In your database `creator` field of `prompts` is likely an `ObjectId`, and not a `User` document as your Go model tells. – icza Aug 30 '23 at 10:38
  • yes thats ture its an object id as from the payload which is being sent from another create-prompt api to refrence to the user Collection – Aakash Raj Aug 30 '23 at 10:50
  • If it is an `ObjectId`, then as the error says, you obviously can't decode that into a value of type `User`. Change your model to `Creator primitive.ObjectId`. Use another query to fetch the user if needed, or use aggregation to fetch both with a single query. – icza Aug 30 '23 at 11:07
  • but what how can i fix this ? – Aakash Raj Aug 30 '23 at 11:25
  • Have you read my last comment? It contains how to fix it. – icza Aug 30 '23 at 11:26
  • hi I chaned the prompt_model to I will provide it in the above code block it gives me the reponse but in the response the creator and the creatorUSer field id is repeated so if you can that this is the right way or should I change something more – Aakash Raj Aug 30 '23 at 19:45

0 Answers0