jquery - coalesce in javascript - Stack Overflow

I am using jQuery, Backbone (and underscore) and RequireJS. I have this code:var products = _.map(ite

I am using jQuery, Backbone (and underscore) and RequireJS.

I have this code:

var products = _.map(items, function(item) {
    return new ProductModel({
        title: item.product.title,
        description: item.product.description,
        link: item.product.link,
        'image-src': item.product.images[0].link,
        'image-height': item.product.images[0].height,
        'image-width': item.product.images[0].width
    });
});

Unfortunately, everything might be null. By everything I mean that item, item.product, item.product.images, item.product.images[0] and so on might be nulls.

I am looking for something like "coalesce" that:

  1. will know how to handle nulls and will not throw exceptions for item.product if item is null.
  2. will allow me to provide a default value if there was a null.

Is there anything like that?

I am using jQuery, Backbone (and underscore) and RequireJS.

I have this code:

var products = _.map(items, function(item) {
    return new ProductModel({
        title: item.product.title,
        description: item.product.description,
        link: item.product.link,
        'image-src': item.product.images[0].link,
        'image-height': item.product.images[0].height,
        'image-width': item.product.images[0].width
    });
});

Unfortunately, everything might be null. By everything I mean that item, item.product, item.product.images, item.product.images[0] and so on might be nulls.

I am looking for something like "coalesce" that:

  1. will know how to handle nulls and will not throw exceptions for item.product if item is null.
  2. will allow me to provide a default value if there was a null.

Is there anything like that?

Share Improve this question edited Dec 15, 2015 at 10:42 Klors 2,6742 gold badges27 silver badges42 bronze badges asked Nov 6, 2012 at 17:48 NaorNaor 24.1k50 gold badges156 silver badges270 bronze badges 1
  • It's better to provide default values in the model... – Soroush Khosravi Commented Nov 6, 2012 at 18:09
Add a ment  | 

6 Answers 6

Reset to default 4

You can use boolean && and rely on short-circuiting:

...
'image_src': item && item.product && item.product.images && item.product.images[0] && item.product.images[0].link,
'image_height': item && item.product && item.product.images && item.product.images[0] && item.product.images[0].height,
...

More likely, you don't want to perform the same test across so many lines. I would store your return value with its various attributes set to some sane default and then conditionally add the real values if your item.product.images[0] is non-null:

var returnObject = { /* default values here */ }, product, image;

if (product = item && item.product) {
    returnObject.title = product.title,
    returnObject.description = product.description,
    returnObject.link = product.link
};

if (image = product && product.images && product.images[0]) {
    returnObject['image-src'] = image.link;
    returnObject['image-height'] = image.height;
    returnObject['image-width'] = image.width;
}

return returnObject;

I would first .filter out the empty products:

var goodItems = _.filter(items, function(item) {
     return 'product' in item;
});

and the simplify the image tests by supplying an empty object if the one in the product doesn't exist:

var products = _.map(goodItems, function(item) {
    var product = item.product;
    var img = (product.images && product.images[0]) || {};
    return new ProductModel({
        title: product.title,
        description: product.description,
        link: product.link,
        'image-src': img.link,
        'image-height': img.height,
        'image-width': img.width
    });
});

If you want a default value for nulls, then you could create a helper function like this:

var coalesce = function(obj, path, defaultValue) {
  while(obj != null && path.length) {
    obj = obj[path.shift()];
  }
  return (obj == null ? defaultValue : obj);
};

You would use it as follows:

coalesce(item, ["product", "title"], "Default title");
coalesce(item, ["product", "images", 0, "link"], "Default image link");

Not sure there is anything like that but I think you may create and use custom functions as below:

    return new ProductModel({
             title: getPorductAttribute(item,'title'),
             description: getPorductAttribute(item,'description'),
             link: getPorductAttribute(item, 'link'),
             'image-src': getImageAttirbute(item,0,'link'),
             'image-height': getImageAttirbute(item,0,'height'),
             'image-width': getImageAttirbute(item,0,'width')
            });


  function getPorductAttribute(item, attributeName){
       if(!(item && item.product)) 
           return defaultValue;
       return item.product.getAttribute(attributeName);
   }

  function getImageAttirbute(item, index, attributeName){
       if(!(item && item.product && item.product.images)) 
           return defaultValue;
       return item.product.images[index].getAttribute(attributeName);
   }

You can use the logical OR operator "||" to coalesce, as described here...

http://pietschsoft./post/2008/10/14/JavaScript-Gem-Null-Coalescing-using-the-OR-Operator

var something = maybeNothing || 0;

Works against both null or undefined.

If you are unsure what the object actually is. You can do the good old try-catch...

var testObject = {
  alpha: {
    beta: null
  },
  gama: {
    delta: null
  }  
};

try {
    console.log(testObject.alpha.beta.gama.delta);
} catch(err) {    
    alert(err.message);
}

This will not break your app, since the error is not throwed. What you can do inside the catch statement is to fill your object with the default that is missing.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745102132a4611336.html

相关推荐

  • jquery - coalesce in javascript - Stack Overflow

    I am using jQuery, Backbone (and underscore) and RequireJS. I have this code:var products = _.map(ite

    12小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信