1

I'm trying to verify if a specific record exist inside a table by a given ID. For example:

var id = 23;
db.count('products',id).done(function(count) {
    if(count>0){
        db.get('products',id).done(function(r) {
            //Do something
        });
    }else{
        alert('No product found');
    }
});

When I try this, I get the following error: uncaught exception: null

I'd really appreciate your help Thanks!.

Kyaw Tun
  • 12,447
  • 10
  • 56
  • 83
Crash Override
  • 411
  • 6
  • 17
  • The error message `uncaught exception: null` worry me. Are you using dev version? It should give a clear message about input argument error. – Kyaw Tun Oct 06 '13 at 01:30
  • I had the same error using this file `ydn.db-isw-core-qry.js`. I only have meningful error messages when I use this: `ydn.db-iswu-core-e-qry-dev.js` – Rudy Oct 25 '13 at 07:28

1 Answers1

1

Your solution is almost correct.

In IndexedDB API, there is no exists method, probably because it can be emulated using count method. But count method accepts only key range, so existence test should be:

var id = 23;
db.count('products', ydn.db.KeyRange.only(id)).done(function(cnt) {
  if (cnt) { // exist

  } else { // no exist

  }
}); 

Another reason, exists method don't exist in the IndexedDB api is that, get don't give error for non-existing key. So you can safely, and recommended, to do:

var id = 23;
db.get('products', id).done(function(product) {
  if (product) { // exist

  } else { // no exist

  }
});

I would like to point out that, in these two ways to detect existence, the first method is more efficient because it avoid deserialization. So if you just need to test for existence, use first method. For retrieving a record, which may or may not exist, use second method.

EDIT:

To query a record by primary key, id, or unique secondary key, sku

/**
* @param {string} id id or sku
* @param {Function} cb callback to invoke resulting record value. If not exists in the
* database, null or undefined is returned.
*/
var getByIdOrSku = function(id, cb) {
  var req = db.get('items', id);
  req.done(function(item) {
    if (item) {
      cb(item) 
    } else {
      db.values('items', 'SKU', ydn.db.KeyRange.only(id), 1).done(function(items) {
        cb(items[0]); // may not have result
      });
    }
  }); 
};

If you prefer promise way:

db.get('items', id).then(function(item) {
   if (item) {
      return item;
   } else {
      return db.values('items', 'SKU', ydn.db.KeyRange.only(id), 1).done(function(items) {
          return items[0];
      });
   }
}).done(function(item) {
   // result query as as id or SKU
   console.log(item);
});
Kyaw Tun
  • 12,447
  • 10
  • 56
  • 83
  • hi, thanks again for your help Kyaw, I tried the second option, many times, but if there is no record that match the given ID, it always throws an error saying that the `product` var (in this particular case) is not defined. I'll try the first option now. :) – Crash Override Oct 06 '13 at 02:40
  • Another thing, if for example I use the first solution and `count` returns `0` because there was no record matching the ID, can I try to match another field in my table? Like a `date` or a `name`? – Crash Override Oct 06 '13 at 04:18
  • You shouldn't receive `product var is not defined`. `product` is input argument of the function. It must be something? It must work. Show me your code. – Kyaw Tun Oct 06 '13 at 06:14
  • `can I try to match another field in my table?` Better use primary key, but secoundary (index) keys are also OK. – Kyaw Tun Oct 06 '13 at 06:15
  • When I get the `var is not defined` error is when I use `db.get('item',1)` but there are no records in that table, I used this code: `db.get('item',1).done(function(r){/*Do something*/});` but the `count` method solved it. – Crash Override Oct 06 '13 at 11:15
  • About the secondary `Index`, how do I define them?, could you give an example on how would you do a search for a record matching a specific `ID` against a specific `field`, but when it fails to match them it tries to match the `ID` against another `field`?. I'm basically trying to make an input form in which you can type the `ID` or the `SKU` of a product in the same input, so I won't know if the user is typing the `ID` or the `SKU`, so I first try to match the entered value against the `ID field`, and if it fails, I'll try to match it against the `SKU field` in my table. Thanks :) – Crash Override Oct 06 '13 at 11:24
  • You should not get `var is not defined` using `db.get('item',1)` whether record exist or not. No bug in library, I just checked my unit test. – Kyaw Tun Oct 06 '13 at 12:59
  • Ok, I'll test it again and see if the error persists, I'll post a screen shot if the error shows up again. Thanks for your help – Crash Override Oct 06 '13 at 19:47