Display if collection field is null


#1

Hi all,

I have a field called RegisteredAt that either has a value NaN (python null) or a date time. On a table on the front-end, I put code like this:

<td>{{#if registeredatcheck}} YES {{/if}}</td>

On my js file, I defined a function like this:

	'registeredatcheck': function(registered){
		var registered = Logins.find().forEach(function(check) {
			if (check.RegisteredAt='NaN'){
				return false;
			}
		});
	},

But this doesn’t seem to work. I want to iterate over the RegisteredAt field and display a YES if it is not equal to NaN.


#2

I think the problem is: = vs == in the line that checks for the NaN. And I would do:

return (isNaN(check.RegisteredAt);

Does that help?


#3

There is not so much context to this story, but I guess your looking for instanceof.

{{#each login in logins}}
  <td>{{registeredAtCheck login}}</td>
{{/each}}
'registeredAtCheck': ({ RegisteredAt }) => {
  return RegisteredAt instanceof Date ?
    'YES' : 'NO';
}

I haven’t tested this code, and using Blaze has been a while for me. But it should work. Maybe you need to use Template.currentData(); in the helper though.


#4

There are a few issues with this test:

  1. You are performing an assignment, not a test (=, not == or ===).
  2. You are using a string, not the NaN value.
  3. Even if you fix those, thanks to the weirdness of JavaScript, you can’t test for NaN like that*. You need to use if (isNaN(check.RegisteredAt)) {

* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN


#5

@robfallows @pwiegers I fixed it to this:

'registeredatcheck': function(registered){
	var registered = Logins.find().forEach(function(check) {
	if (isNaN(check.RegisteredAt)) {
		return true;
		}
	});

But it still doesn’t display YES (or anything) in the data context (the other fields work) -

{{#each getlogins}} //lines skipped {{#if registeredatcheck}} YES {{/if}} {{/each}}

Also, my UI currently renders 3000 rows. This function is causing it slow down to the point that it crashes on Chrome. Is there a simpler way to check for NaN without doing a forEach?


#6

Is it definitely NaN in the database - if you use the mongo shell for instance?


#7

Yes, on shell I see this:

{
"_id" : ObjectId(“57a6a810f78acebe815ed9a1”),
“Username” : “xx”,
“Firm” : “xx”,
“Region” : “EMEA”,
“Name” : “xx”,
“Recordtype” : “xx”,
“RegisteredAt” : NaN
}


#8

Ah, my bad. I focused entirely on the logic of the test and not on the surrounding code. You cannot return a result from the helper by doing a return from inside a callback (forEach): that just returns from the callback. You need to restructure your helper to return a cursor (or an array):

registeredatcheck(registered) {
  var registered = Logins.find({RegisteredAt: NaN});
}

Note: using NaN in a query is supported in MongoDB, but I’ve not tested it in minimongo. Let me know! :slight_smile:


#9

Thanks @robfallows, I just tried that, but it’s still not returning a YES for any value of RegisteredAt. Here’s my full logins.js file:

import { Template } from ‘meteor/templating’;

Logins = new Mongo.Collection(‘logins’);

if(Meteor.isClient){
Meteor.subscribe(‘getlogins’);
Template.loginstemplate.helpers({
‘ready’: function () {
return Template.instance().subscriptionsReady();
},
‘getlogins’: function(){
return Logins.find();
},
‘countusers’: function(){
return Logins.find({“RegisteredAt”:{$ne:NaN}}).count();
},
‘countactiveusers’: function(){
return Logins.find().count();
},
‘registeredatcheck’: function(registered){
var registered = Logins.find({“RegisteredAt”: NaN});
},
});
}

if(Meteor.isServer){
Meteor.publish(‘getlogins’, function(){
return Logins.find({});
});
}

And my logins.html template uses this:

{{#each getlogins}}
//lines skipped
{{#if registeredatcheck}} YES {{/if}}

{{/each}}


#10

@robfallows Also, I think it does work in Minimongo because my function countusers which looks up NaN does work on my front-end!


#11

@robfallows I almost got it working by using this:

	'registeredatcheck': function(){
		if (this.RegisteredAt =='Aug  8 2016  8:08AM') {return true}
	},

Now, this returns true. Can I switch the ==‘Aug 8 2016 8:08AM’ to test for either NaN or data type==date? Testing for NaN using isNaN(this.RegisteredAt) returns true for all documents.


#12
this.RegisteredAt instanceof Date

#13

@smeijer thanks, I was just trying this as you responded like this:

	'registeredatcheck': function(){
		if (this.RegisteredAt instanceof Date) {return true}
	},

But it never returns true. Here’s a sample from mongo shell:

{
"_id" : ObjectId(“57a6a810f78acebe815ed9a6”),
“Username” : “xx”,
“Firm” : “xx”,
“Region” : “EMEA”,
“Name” : “xx”,
“Recordtype” : “xx”,
“RegisteredAt” : “Aug 8 2016 8:08AM”
}


#14

I guess you have some serious typing issues in your database. If that check doesn’t work, than the date is not stored as an Date type.

Alternatives you can use are:

// check if it is not a NaN
return isNaN(this.RegisteredAt) === false;

// try parse to a date, if it works, it's a valid date
return Date.parse(this.RegisteredAt) instanceof Date;

// parsing returns NaN if it doesn't work. Check if it didn't work.
return isNaN(Date.parse(this.RegisteredAt)) === false;

// or really wrong, as it seams you're storing dates as strings
return typeof this.RegisteredAt === 'string'

#15

@smeijer So it looks like the date is a string and it works with that test. Thanks for that - that was useful for debugging. I will check the Python script that sends down this date value.