1

Say I have a json of observables :

self.name = ko.observable('Arnab');
self.surname= ko.observale('Bhagabati')

var person = {
  name:ko.observable('Arnab'),
  lastName= ko.observale('Bhagabati')
}

I can access the name of person by console.log(person.name());

How do I check whether my person has a knockout observable property called, say salary?

if (typeof person.salary() !== 'undefined')

gives params.salary is not a function

A Nice Guy
  • 2,676
  • 4
  • 30
  • 54

5 Answers5

5

How do I check whether my person has a knockout observable property called, say salary?

(emphasis mine)

If you use a check along the lines of if (ko.unwrap(person.salary)), like the other answers suggest, you're basically checking if there's a defined salary property.

I.e.:

person = { salary: undefined };
person = { };
person = { salary: ko.observable() };

Will all return true for typeof ko.unwrap(person.salary) === "undefined"

If I take what you wrote literally, this doesn't answer whether the 'person' object has an observable property called salary.

To answer this question, you'll need ko.isObservable:

var persons = [
  [{ }, "{ }"],
  [{ salary: undefined }, "{ salary: undefined }" ],
  [{ salary: ko.observable() }, "{ salary: ko.observable()" ]
]

var check1 = person => typeof ko.unwrap(person.salary) === "undefined";
var check2 = person => ko.isObservable(person.salary);

console.log(check1.toString());
persons.forEach(([p, c]) => console.log(c, "->", check1(p)));

console.log(check2.toString());
persons.forEach(([p, c]) => console.log(c, "->", check2(p)));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

It might be that I took your question too literally, and all you need is ko.unwrap, but I felt I had to share the difference

user3297291
  • 22,592
  • 4
  • 29
  • 45
4

observables are functions. If there is no salary property, person.salary() will throw an exception.

So you can use:

if (typeof ko.unwrap(person.salary) !== 'undefined')
{

}

unwrap returns the value of the property, irrespective of whether it's observable or not.

Refer to this question on more info

adiga
  • 34,372
  • 9
  • 61
  • 83
0

In the following code, != checks for both null and undefined:

if (person.salary != null) {
    // ...
}
M0nst3R
  • 5,186
  • 1
  • 23
  • 36
Expressingx
  • 1,480
  • 1
  • 14
  • 39
0
var val = ko.unwrap(person.salary);

and

console.log(ko.unwrap(person.salary));

will work no matter whether person.salary is observable or not.

TSV
  • 7,538
  • 1
  • 29
  • 37
0

If you want a quick solution, just see if the object type is a function, and then add a couple of checks for knockout specific functions to exist in it. This is handy to use in ko.computed, when you are pretty dern sure that the observable are GOING to be there, but aren't yet.

var isKoObservable = function(obs) {
  var retVal = false;
  if (typeof obs === "function") {
    if (typeof obs.subscribe === "function" && typeof obs.notifySubscribers === "function") {
      // its HIGHLY likely to be an observable or observableArray
      retVal = true; 
    }
  }

  return retVal;
}

See this SO answer for details: how to tell if a javascript variable is a function

CarComp
  • 1,929
  • 1
  • 21
  • 47