Nested array in smart view (V7)

Expected behavior

Access to nested array through records in smart view.

I have an Order model as follow:

const OrderSchema = Mongoose.Schema(
    {
      orderNumber: String,
      collect: {
        type: Mongoose.Schema.Types.ObjectId,
        ref: 'collect',
        index: true
      },
      orderItems: [
        {
          productId: {
            type: Mongoose.Schema.Types.ObjectId,
            ref: 'product',
            index: true
          },
          status: Number,
          quantity: Number,
          unitPrice: Number,
          unitPriceDiscounted: Number,
          promotionType: Number,
          promotionAmount: Number,
          promotionCode: String,
          aspttDiscountAmount: Number,
          isLicenceApproved: Boolean,
          taxReceiptSent: Boolean
        }
      ]
}

I want to display info about orderItems in the smart view

Actual behavior

I can display data such as orderNumber but I can iterate through orderItems to display data inside.

Failure Logs

No failure logs

Context

Please provide any relevant information about your setup.

"meta": {
    "liana": "forest-express-mongoose",
    "liana_version": "7.8.2",
    "stack": {
      "database_type": "MongoDB",
      "engine": "nodejs",
      "engine_version": "12.22.1",
      "orm_version": "5.9.4"
    }
  }

Project Name: joinly-forest

Hi @Guiguijo,

Can you please share the code of your smart view :thinking: ?

yes @vince

component:

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { 
  triggerSmartAction,
  getCollectionId, 
  loadExternalStyle, 
  loadExternalJavascript 
} from 'client/utils/smart-view-utils';
import { inject as service } from '@ember/service';

export default class extends Component {
  @tracked currentRecord = null;
  @tracked payment;
  @service store;
  
  
  @action
  setDefaultCurrentRecord() {
    console.log('------> this.args', this.args.records);
    if (!this.currentRecord) {
      this.currentRecord = this.args.records.firstObject;
      console.log('------> this.currentRecord', this.currentRecord);
      
    }
  }
  
  @action
  triggerSmartAction(...args) {
    return triggerSmartAction(this, ...args);
  }
  
  @action
  selectRecord(record) {
    this.currentRecord = record;
  }
  
  
}

Template

<div class="wrapper-view" {{did-insert this.setDefaultCurrentRecord}}>
  <div class="wrapper-list">
    {{#each @records as |record|}}
      <a href="#" {{on 'click' (fn this.selectRecord record)}}>
        <div class="list--item {{if (eq this.currentRecord record) 'selected'}}">
          <div class="list--item__values-left">
            <h3><span>Commande</span> {{record.forest-orderNumber}}</h3>
            <p><span>ID Joinly</span> : {{record.forest-_id}}</p> 
            <p><span>En date du</span> : {{moment-format record.forest-createdAt 'LLL'}}</p>
          </div>
          
        </div>
      </a>
    {{/each}}
  </div>
  
  <div class="wrapper-card">
    <div class="card--title">
      <h1>
        <span class="c-smart-view_icon fa fa-{{@collection.iconOrDefault}} fa-1x"></span>
        Commande: {{this.currentRecord.forest-orderNumber}}
      </h1>
      <small>ID Joinly: {{this.currentRecord.id}}</small>
      
      {{#each this.currentRecord.forest-orderItems as |orderItem|}}
        <p> {{orderItem.quantity}}</p>
      {{/each}}
    </div>
  </div>  
</div>

Something that might help you in the future, in the template you have access to an helper called {{log}} which just do a console.log from the template. So in your case to see if your orderItem is correct you could have done {{log orderItem}}

The issue, I think it’s just because you are baddly accessing the quantity, try: {{orderItem.forest-quantity}}

Let me know if that fix your issues :slight_smile:

Hi Vince,

you’re right I must use forest-quantity, however it stil does not work.

If I log as you suggest, I can’t see nothing:

<div class="wrapper-card">
    <div class="card--title">
      <h1>
        <span class="c-smart-view_icon fa fa-{{@collection.iconOrDefault}} fa-1x"></span>
        Commande: {{this.currentRecord.forest-orderNumber}}
      </h1>
      <small>ID Joinly: {{this.currentRecord.id}}</small>
      log orderItems: {{log this.currentRecord.forest-orderItems}}
      {{#each this.currentRecord.forest-orderItems as |orderItem|}}
        test log: {{log orderItem}}
        <p> {{orderItem.forest-quantity}}</p>
      {{/each}}
    </div>
  </div>  

image

and I am sure to have since if I go to the detail view I have this:

Stupid question but did you use the autocompletion :thinking: ? Just to make sure you type the right thing especially for forest-orderIttems

yes:
image

however the autocompletion does not work on the orderItem inside the loop:

image

It suggests me props that belong to order object

@vince

are you able to reproduce this case ?

And what do you have in your console ?

I can see this error:

and if I console.log() the current orde, I can see that:

Okey so the error comes from the fact that the array is empty. And the array is empty cause the request was canceled. Do you see any request leaving ? Especially on GET /forest/orders/:recordId/orderItems or something like that

nop… I can’t see any cancelled request:

Moreover I can see that the requests fetching the orders always return empty orderItems array

Hello @Guiguijo,

Just a quick question, did you override any routes that could be related to the fact the orderItems array is empty?

Re @Guillaume_Cisco ,

I don’t think so.

Here are my order routes:

const express = require('express')
const { PermissionMiddlewareCreator } = require('forest-express-mongoose')

const {
  handleDeleteOrder,
  handleGetOrderPayments,
  handleDeleteOrderArticle,
  handleSendOrderBookingConfirmation,
  handleSendOrderRegistrationConfirmation
} = require('./../manager/order/order.handler')

const router = express.Router()
const permissionMiddlewareCreator = new PermissionMiddlewareCreator('order')

// Smart Relationships
router.get('/Order/:id/relationships/payments', handleGetOrderPayments)

// Smart actions
router.post('/actions/envoyer-confirmation-de-reservation', permissionMiddlewareCreator.smartAction(), handleSendOrderBookingConfirmation)
router.post(
  '/actions/envoyer-confirmation-d-inscription',
  permissionMiddlewareCreator.smartAction(),
  handleSendOrderRegistrationConfirmation
)
router.post('/actions/supprimer-un-article', permissionMiddlewareCreator.smartAction(), handleDeleteOrderArticle)
router.post('/actions/supprimer-commande', permissionMiddlewareCreator.smartAction(), handleDeleteOrder)

module.exports = router

Hello @Guiguijo,

Indeed I do not see any overrides on CRUD routes.
Would you be able to debug the called route you shew to me in your screen?
I don’t understand why there is only orderItems, orderNumber, createdAt and _id. Why is there not the collect attribute?
Can you show me the relationships and maybe the included data?

Furthermore, in order to reproduce your case, it would be great for me to have the structure of your mongoose schemas. At least the ones dealing with your Order schema.

Thank you,

@Guillaume_Cisco you can see my order Schema at the top of the conversation.

I send other info ASAP