Search code examples
reactjsmongodbuser-interfacemongoose-schemamern

How to post list item dynamically from client side - MERN


I am trying to build a MERN stack app with a theme of recipe books, I am not able to finalize the logic of recipe schema. The app is about a recipe's where people will post their recipes publicly, so the recipe has to be build dynamically. I need some advice or suggestion on how to map things. Here are the details of my app.

Recipe Schema

const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;

const recipeSchema = new mongoose.Schema(
    {
        nameOfRecipe:{ // Title 
            type: String,
            trim: true,
            required: true,
            maxlength: 32
        },
        description: { // Short description
            type: String,
            trim: true,
            required: true,
            maxlength: 32
        },
        category: { // This will populate from another schema
            type: ObjectId,
            ref: "Category",
            required: true
        },
        ingredientName: { // Ingredient title
            type: String, 
            maxlength: 25 
        },
        quantity: {
            type: Number, // Ingredient Quantity
            default: 0,
            min: 0,
            max: 9999
        },
        type:{
            type: String, // Ingredient type example: lb/kg/cups/tbsp
            trim: true,
            required: true,
            maxlength: 10
        },
        photo: { // image
            data: Buffer,
            contentType: String
        },
        method: { // Steps to cook
            type: String,
            required: true,
            maxlength: 2000
        },
        people: { // Number of people suggested to be served
            type: Number
        }
    },
    { timestamps: true }
);

module.exports = mongoose.model("Recipe", recipeSchema);

I am not satisfied in my Schema too as I want the ingredient display as example "80grm Whole wheat flour" but with the schema I created above have all three as different properties and key values whereas it has to be displayed as one single string. How is this possible?

I want a UI similar to this...

Sample Look

Like how the "Ingredient" are in bullet and the "Instructions" in ordered list. But the issue is how is this possible from client side. Please advice....!!!


Solution

  • ingredients and instructions must be array.

    So you need can create embedded schemas for ingredients and instructions like this: (note that I removed some fields for simplicity, and renamed method fiel to instructions which makes more sense)

    const ingredientSchema = new mongoose.Schema({
      ingredientName: {
        type: String,
        maxlength: 25
      },
      quantity: {
        type: Number,
        default: 0,
        min: 0,
        max: 9999
      },
      type: {
        type: String, // Ingredient type example: lb/kg/cups/tbsp
        trim: true,
        required: true,
        maxlength: 10
      }
    });
    
    const instructionSchema = new mongoose.Schema({
      order: Number,
      step: {
        type: String,
        required: true,
        maxlength: 2000
      }
    });
    
    const recipeSchema = new mongoose.Schema(
      {
        nameOfRecipe: {
          type: String,
          trim: true,
          required: true,
          maxlength: 32
        },
        description: {
          type: String,
          trim: true,
          required: true,
          maxlength: 32
        },
        ingredients: [ingredientSchema],
        instructions: [instructionSchema]
      },
      { timestamps: true }
    );