object-path icon indicating copy to clipboard operation
object-path copied to clipboard

Return the result of a function property

Open ngryman opened this issue 10 years ago • 4 comments

Hi,

I think it would be really nice to detect if a property is a function and return it's result. It could be handy when you want get a value out of a getter.

If you still want to get the function itself, it could be specified via an optional parameter to get. You could also create another method that does this, like fetch or getOrCall.

What do you think? Thanks!

ngryman avatar Sep 26 '14 19:09 ngryman

Well, what about the arguments of those functions? And their context? I think it's possible for you to achieve what you want if add a helper method to objectPath:

objectPath.method = function(obj, path, args){
  var fn = objectPath.get(obj, path);
  if (typeof fn === 'function') {
     return fn.apply("??", args); // how would the context be properly applied in here?
  }
  return fn;
};

you'd call it like:

objectPath.method(obj, ['get','the','func'], [1,2,3]);

pocesar avatar Sep 26 '14 20:09 pocesar

The goal is to be able to fetch data from properties we don't know the nature of. Using objectPath.method involves that you know it will be a function.

I'm proposing something very similar to lodash's result: http://lodash.com/docs#result. It's only meant to handle a very simple and widespread use case, out of the box. If the user needs something more advanced, with arguments and a custom context, he will enhance object-path himself.

The default context could be deducted by taking the n-1 object in the hierarchy.

A object like this:

var person = {
  avatar: {
    url: function() { ... }
  }
}

Would be retrieved like this:

var url = objectPath.get(person, 'avatar.url');

The context would be person.avatar.

ngryman avatar Sep 26 '14 21:09 ngryman

Oh I forgot to illustrate your example, it would roughly be something like this:

objectPath.method = function(obj, path, args){
  var fn = objectPath.get(obj, path);
  var ctx = (path.length == 1 ? obj : objectPath.get(obj, path.pop() && path);
  if (typeof fn === 'function') {
     return fn.apply(ctx, args);
  }
  return fn;
};

ngryman avatar Sep 26 '14 21:09 ngryman

The idea doesn't seem bad to me if we keep the use case simple. We would also need to find the right name and interface. For example, I think we should keep the same interface of objectPath.get(), we shouldn't pass any argument, a getter is usually without arguments, otherwise we would fall in weird situations. This is the use case I would support:

var a = {
  b: function() {
    return {c: 'val'}
  }
}

objectPath.ourNewMethod(a, 'b.c') === 'val'

Same for the setter.

What do you think @pocesar ?

mariocasciaro avatar Sep 29 '14 08:09 mariocasciaro