Search code examples
javascriptpromisees6-promise

Adding implementation to Promise.resolve


I want to create a small script to check model is valid or not via using isValid method instead of then method.

Here is the script using then method:

$('button').click(function () {
  let model = Promise.resolve({
    then(x, y) {
      let isValid = $('input[type=text]').val().length > 0;
      x(isValid);
    }
  });
  
  model.then(isValid => console.log(isValid));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" />
<button>check</button>

My goal:

if (model.isValid()) {
    console.log('model is valid.');
}

I've tried:

$('button').click(function () {
  let model = Promise.resolve({
    isValid() {
      let isValid = $('input[type=text]').val().length > 0;
      return isValid;
    }
  });
  
  if (model.isValid()) {
    console.log('model is valid.');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" />
<button>check</button>

Error message:

Uncaught TypeError: 'model.isValid' is not a function

My question: how can I define isValid function in this case?


Solution

  • You second implementation get that runtime error because Promise.resolve returns:

    a Promise object that is resolved with the given value. If the value is a thenable (i.e. has a "then" method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value.

    So, if you define promise like that:

     Promise.resolve({
        isValid() {
          let isValid = $('input[type=text]').val().length > 0;
          return isValid;
        }
      }); 
    

    You are returning an object that is not thenable (it has not a then method, but a isValid one), so you cannot simply do model.isValid() but you have to:

    $('button').click(function () {
      let model = Promise.resolve({
        isValid() {
          let isValid = $('input[type=text]').val().length > 0;
          return isValid;
        }
      });
      
      model.then(res => {
          if (res.isValid()) {
            console.log('model is valid.');
          }
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <input type="text" />
    <button>check</button>