findOne works outside but is 'undefined' when called inside a function

Server side code

I don’t understand why it’s happening. If I’m calling inside a function:

res = Collection.findOne({ key: value });
localVar = res.value;

I get an Exception in callback of async function: TypeError: Cannot read property 'value' of undefined error.

If I’m calling the same statement outside of the function then it’s working fine and it delivers the correct document back.

What am I doing wrong here?

On the client side ‘findOne’ is async then you must ‘guard’ function call result.
For example:
localVar = res && res.value;

EDIT:
Sorry don´t see ‘server side code’.
I guest your problem is related to your code, not a Meteor issue. Put a repo or some real code to see it.

That’s not true. findOne is syncronous on both client and server. It’s just that the document you’re trying to find on the client sometimes isn’t there yet (e.g. subscription isn’t ready).

1 Like

I thought it was async on client that´s why it must called inside a reactive consumer context like: Blaze template helper’s or Tracker.autorun …

On client side all not blocker I/O functions are async cause browser´s single-threaded.

The thing is reactive functions (computations) act like callback since they are called on data change, but findOne give you a result (or nothing) immediately.

I like think is ‘async’ cause it help remember that I cannot expect inmediate result from the call. Is erroneous treat it like a normal ‘sync’ function.

I high porcentage of meteor incomers, me include, bitter this until understand Tracker and reactive approach.

On server side findOne is really ‘sync’, it block the code flow until call return with a ‘valid’ value.

You’re confusing async functions with a function that is being called syncronously when the data isn’t there yet.

If the document is in minimongo, findOne returns it immediately, blocking on the client (albeit for a very short amount of time) until is has done so. If the document is not in minimongo, findOne returns immediately with null (again, blocking until it does so).

The part that is actually async is getting the document(s) into minimongo from the server (usually via pub/sub). When Meteor.subscribe is called, that sends a request for documents off to the server and the client side code keeps running, so Meteor.subscribe is an async function.

That convinces me @babrahams, thanks for pointed out.

But actually I need a mind tag to mark, remember, this kind of functions cause his behaviour.

Clearly ‘async’ is inaccurate but better than nothing. Any ‘tag’ advice?

Reactive…
The flow of the program is modified, you don’t write imperative code (do A, then B, then C) but more declarative (B depends on A value like this). You don’t bother anymore about “when” (too late or too early…) you code is firing, since in the end it will fire to do something useful when data is ready. Which means you should be prepared for your code to run multiple times, and that should not cause a problem.

3 Likes