0

I am doing a tutorial course, and I am stuck on this part, I want to display the properties of the Product which is appearing in console.log but not on the web page. The confusing part is that console.log is showing the product correctly, but not the front-end.

enter image description here

This is the HTML front-end:

<div class="grid mb-5" *ngFor="let orderItem of order.orderItems">
        <div class="col-2">{{ orderItem.product?.name }}</div>
        <div class="col-2">{{ orderItem.product?.brand }}</div>
        <div class="col-2">{{ orderItem.product?.category?.name }}</div>
        <div class="col-2">{{ orderItem.product?.price | currency }}</div>
        <div class="col-2">{{ orderItem.quantity }}</div>
     </div> 

Here is Order TS

/* eslint-disable @typescript-eslint/no-explicit-any */
import { User } from '@eshop-repository/users';
import { OrderItem } from './order-item';

export class Order {
  
  id?: string;
  orderItems?: OrderItem[];
  shippingAddress1?: string;
  shippingAddress2?: string;
  city?: string;
  zip?: string;
  country?: string;
  phone?: string;
  status?: number;
  totalPrice?: string;
  user?: User;
  dateOrdered?: string;
  _id?: string;
  
}

Here is the code for Order Item TS:

/* eslint-disable @nrwl/nx/enforce-module-boundaries */
import { Product } from "@eshop-repository/products";

export class OrderItem {
    product?: Product;
    quantity?: number;
  }

Model:

const mongoose = require ('mongoose');

const orderSchema = mongoose.Schema ({

    orderItems: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'OrderItem', 
        required: true
    }],
    shippingAddress1: {
        type: String, 
        required: true,
    },
    shippingAddress2: {
        type: String,
    },   
    city: {
        type: String,
        required: true, 
    },
    zip: {
        type: String,
        required: true, 
    },
    country: {
        type: String,
    },
    phone: {
        type: String,
        required: true, 
    },
    status: {
        type: String,
        required: true, 
        default: 'Pending',
    },
    totalPrice: {
        type: Number,
    },
    user: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
    },
    dateOrdered: {
        type: Date, 
        default: Date.now,
    }
})
orderSchema.virtual('id').get(function() {
    return this._id.toHexString();
}); 
orderSchema.set('toJSON', {
    virtuals: true,
}); 
exports.Order = mongoose.model('Order', orderSchema); 

Route:

router.get(`/:id`, async (req, res) => {
    
    let order = await Order.findById(req.params.id)
    .populate('user', 'name') 
    .populate('orderItems') 
   if(!order) {
        res.status(500).json({success: false})
    }
    res.send (order);
})

Schemda of order-item:

const mongoose = require ('mongoose');

const orderItemSchema = mongoose.Schema ({

quantity: {
    type: Number, 
    required: true
}, 
product: {
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'Product'   
}
    
})
ENN9
  • 19
  • 6
  • Does this answer your question? [Populate nested array in mongoose](https://stackoverflow.com/questions/19222520/populate-nested-array-in-mongoose) – Yong Shun May 05 '23 at 08:44
  • Thanks Yong, but I doubt I can find my answer here, these are probably very old. Second, the console.log shows that product is being fetched. So I doubt the error lies there, maybe I am wrong. – ENN9 May 05 '23 at 08:57
  • From your first screenshot, the `product` shown is an ObjectId rather than an object. So that's why I share the link above, which possible help you to fetch the product object via Mongoose. – Yong Shun May 05 '23 at 09:02
  • Aah I see, can you tell me which method to use to properly give the nested array in mongoose, my version is 6.9.1, thanks Yong! – ENN9 May 05 '23 at 09:07
  • Simply check when order are completely fetched then only that component should visible. See the small i icon in the console. That means output came later than the consoled value. – Adesh Kumar May 05 '23 at 09:34
  • Have you tried this? `.populate({ path: "orderItems", populate: { path: "product", model: "Product" } })` – Yong Shun May 05 '23 at 09:43
  • Thank you Yong, I tried it and now the product appears NULL. See here: https://paste.pics/NRWER – ENN9 May 05 '23 at 10:07

1 Answers1

0

based on the screenshot, you can clearly see that the product contains only a string. but you're treating it as a object and trying to use its properties in the ngFor