Ember cp-validations - belongsTo validation

I didn’t find the answer in the examples provided in ember-cp-validation dummy app as well in their presentation.

I have to validate a language in the following model:

# models/shop-language.js

import DS from 'ember-data';
import { validator, buildValidations } from 'ember-cp-validations';

const Validations = buildValidations({
  language: {
    description: 'Language',
    validators: [validator('ds-error'), validator('presence', true)]
  },

  shop: {
    description: 'Shop',
    validators: [validator('ds-error'), validator('presence', true)]
  },
});

export default DS.Model.extend(Validations, {
  shop: DS.belongsTo('shop', { async: true }),
  language: DS.belongsTo('language', { async: true }),
  modifiedBy:  DS.attr('string')
});

On which property should I use v-getin the template if I load 2 models from my route:

#routes/shop-languages.js

model() {
    return RSVP.hash({
      shopLanguages: this.store.query('shop-language', { shop_id: this.get('currentShop.shop').get('id')}),
      languages: this.store.findAll('language')
    });
  },

Here is the template:

#templates/shop-languages.hbs
...
{{#each model.shopLanguages as |shopLang|}}
        <li class="list-group-item">
          {{shopLang.language.tag}}
          <button type="button" class="btn btn-danger btn-sm" disabled={{isDeleteButtonDisabled}} {{action "deleteLanguage" shopLang}}>
            <span class="oi oi-trash"></span>
          </button>
        </li>
      {{/each}}

  <form {{action "saveLanguage" aLanguage on="submit"}} class="form-inline">

          {{#if showLanguageError}}
            <div class="alert alert-danger">
              {{v-get aLanguage 'id' 'message'}}
            </div>
          {{/if}}

          <div class="col-sm-2">
            {{#power-select
              class="form-control"
              placeholder=placeholderText
              selected=aLanguage
              options=model.languages
              searchField="tag"
              noMatchesMessage=(t 'components.language.labels.not.found')
              onchange=(action (mut aLanguage))
              focus-out=(action (mut showLanguageError) true)
              as |language|
            }}
            {{language.tag}}
            {{/power-select}}
          </div>

<div class="form-check sm-2">
            <button type="button" type="submit" class="btn btn-success btn-sm">
              <span class="oi oi-plus"></span>
              {{t 'buttons.add'}}
            </button
...

Here is how I tried to save a newly added language in the route:

# routes/shop-languages.js

actions: {
...
  async saveLanguage(aLanguage) {
   ...
  try {
        await shopLanguage.save();
        controller.set('aLanguage', '');
        route.get('flashMessages').success(route.get('i18n').t('flash.language.added'));
        route.refresh();
      } catch(response) {
        let error = response.errors[0];
        console.log('+++++ in CATCH block error: ' + error);
        if (error.status !== "422") {
          throw response;
        }
      }

It prints the error to the console but displays nothing in the template … :frowning: The response I get from Rails backend if language is not selected:

{"message":"Couldn't find Language"}

Should parse in some way this message to be able to display it ? And the error object is as follows:

{status: "404", title: "The backend responded with an error", detail: "[object Object]"}

Thank you.

A few things stand out as possibly wrong:

  1. showLanguageError is not set to a truthy value so the error message is not going to be rendered.
  2. You have {{v-get aLanguage 'id' 'message'}} in the template but the validation is not set up on the id property of aLanguage.
  3. I suppose aLanguage is a ShopLanguage but the code snippets don’t tell us that.

HTH

Even if I remove ifcondition (this would enable displaying errors on the form display), nothing happens. That’s why I wonder what is the syntax to use when calling v-get:

# extact from RARWE book, page 291.

{{v-get model 'email' 'message'}}

All the provided use cases suppose to have ONE model defined in the route (like creating a User or a Post, for example).

aLanguage is an instance of Language model to be selected from the drop-down list (value to submit → language.id, displayed value → language.tag.

As I described earlier, the relations are defined as follows between Shop, ShopLanguage and Language models:

Shop: hasMany ShopLanguages
ShopLanguage: belongsTo Shop
ShopLanguage: belongsTo Language

You can see how it looks in the below screenshot.

It doesn’t matter what your model is in the corresponding route. What matters is which object you added the validations onto that you’re checking.

v-get is just a nifty helper to prevent you from having to write lengthy expressions (see [the relevant page from the docs here).

So {{v-get model 'email' 'message'}} desugars to {{model.validations.attrs.email.message}}. In your case, {{v-get aLanguage 'id' 'message'}} is equivalent to {{model.validations.attrs.id.message}} which might not be what you want – unless you added a validation to the id property.

Hi, I am also trying to get access to a validation I have Models as follows: “recommendedProduct” belongsTo “recommendation” belongsTo “recommendedAdjustment” belongsTo “report”. I am trying to access the validation on recommendedProduct in report template with ember-cp-validations but I’m not getting anything on screen?

Tried all sorts of variations of: model.recommendedAdjustment.recommendation.recommendedProduct.recommendedProductSuppliers No one is helping on Discord. Docs don’t have enough information to solve the issue

  {{#if (v-get model.recommendedAdjustment.recommendation.recommendedProduct.recommendedProductSuppliers 'isInvalid')}}
   <div class="col-sm-4">Sole supplier required</div>
    {{action 'setSoleSupplierTrue'}}
  {{/if}}
  {{#if (v-get model.recommendedAdjustment.recommendation.recommendedProduct.recommendedProductSuppliers 'isValid')}}
   <div class="col-sm-4">Sole supplier not required</div>
    {{action 'setSoleSupplierFalse'}}
  {{/if}}

I expect one div to show depending on if the recommendedProductSuppliers validation in the recommendedProduct Model is valid or not.