ember.jsember-cliember.js-2

Using Not Or/Not And on Ember CLI


So I'm wondering if there is a computed string property that negates the current boolean value of a property. For example, in the computed property 'isDisabledSubmit' below, I added an exclamation mark in front of isValidEmail and isValidMessage in attempt to negate the property value. This doesn't work, but you can probably assume what I'm trying to accomplish. I could get it to work by adding two extra properties isInvalidEmail and isInvalidMessage, but this seems a bit excessive in a large app... Is there a way to do a not and and a not or/ negate a property inside an and/or?

export default Ember.Controller.extend({
contactForm: false,
contactEmail: '',
contactMessage: '',
isValidEmail: Ember.computed.match( 'contactEmail', /^.+@.+\..+$/ ),
isValidMessage: Ember.computed.gte('contactMessage.length', 10),
isDisabledSubmit: Ember.computed.or( '!isValidEmail', '!isValidMessage') 
});

Possible, but tedious solution

export default Ember.Controller.extend({
contactForm: false,
contactEmail: '',
contactMessage: '',
isValidEmail: Ember.computed.match( 'contactEmail', /^.+@.+\..+$/ ),
isValidMessage: Ember.computed.gte('contactMessage.length', 10),
//Add negated version of previous properties...tedious approach...
isInvalidEmail: Ember.computed.not('isValidEmail'),
isInvalidMessage: Ember.computed.not('isValidMessage'),
//
isDisabledSubmit: Ember.computed.or( 'isInvalidEmail', 'isInvalidMessage') 
});

Solution

  • In short no. Ember.js forces you to be explicit on what property is available and helps your code to be readable with convenient functions like Ember.computed.match and Ember.computed.not.

    However, if your intention is to use these computed properties in templates, you can bypass this limitation with a custom helper. Just create a file app/helpers/reverse.js with the following content:

    import Ember from 'ember';
    
    export function reverse([value]) {
      return !value;
    }
    
    export default Ember.Helper.helper(reverse);
    

    You will then be able to branch depending on the inverse of a computed property:

    {{#if (reverse isValidEmail)}}
    {{/if}}
    

    Is the same as

    {{#if isInvalidEmail}}
    {{/if}}
    

    Be aware this method is less explicit and only works inside templates.