2

I have an issue where, when I log a JavaScript object (a subscription handler) in Meteor I am able to see the field 0 but I am unable to retrieve it from the code.

I am using numtel:mysql package.
Here is the entire Meteor code used to reproduce the issue:

Bootstrap

Meteor.startup(function() {
    Meteor.readLiveDb = new LiveMysql(Meteor.Config.mysql.read);
    Meteor.writeLiveDb = new LiveMysql(Meteor.Config.mysql.write);

    var closeAndExit = function() {
        Meteor.readLiveDb.end();
        Meteor.writeLiveDb.end();
        process.exit();
    };
    // Close connections on hot code push
    process.on('SIGTERM', closeAndExit);
    // Close connections on exit (ctrl + c)
    process.on('SIGINT', closeAndExit);

});

Publish Code

Meteor.publish("checkLoginSubscription", function(username, password) {
    if(typeof username === undefined || typeof password === undefined) {
        throw new error('Username or password cannot be blank');
        return;
    }

    var user = Meteor.readLiveDb.select(
        'select * from users where username = "' + username + '" and password = "' + password + '"', [{
            table: 'users'
        }]
    );

    return user;
});

Event Code

    Template.login.events({
    'submit #loginform': function(event) {
        event.preventDefault();
        $('#message').fadeIn();
        var username = event.target.username.value;
        var password = CryptoJS.MD5(event.target.password.value).toString();
        console.log('The Password entered is ', password);
        if(username == '' || password == '') {
            $('#message').addClass('alert-danger').removeClass('alert-success');
            $('#message').html('Username or password cannot be blank');
            return;
        }
        $('#message')
            .html('<img src="img/loaders/1.gif" alt="loading" /> Logging you in...')
            .addClass('alert-success')
            .removeClass('alert-danger');

        var cLogin = new MysqlSubscription('checkLoginSubscription', username, password);

        console.log(cLogin); // This is the variable holding the object

        console.log(cLogin[0]); //undefined!
    }
});

On the last line you can see the log:

console.log(cLogin);

Console.log result screenshot

When I try to get the 0: Object part of the handler it returns undefined.

What is going wrong? How can I access this data?

Kyll
  • 7,036
  • 7
  • 41
  • 64
Guns
  • 2,678
  • 2
  • 23
  • 51

2 Answers2

2

Meteor subscriptions are reactive stuff.
When you cast one it starts reaching over to the server's publication handler.

This publication has two ways to resolve:

This signals to the client that the publication is ready and that he can start using the data.

To keep track of this, you have again two ways:

  • The native way: provide a callback. I'm not sure if SQL subscriptions allow it though.
  • The Meteor way (which I know is supported thanks to your screenshot) : ready().
    ready() is a reactive data source (hence the pun). It means you can run a Tracker computation with it!
    Such computations are natively implemented in template helpers.
    Here is another way to implement it using the native Tracker goodness:

    Tracker.autorun(function doStuffOnceDataIsReady() {
      if(cLogin.ready()) {
        doStuff();
      }
    });
    

Seeing your use case, you might want to delve in template subscriptions or template computations.

Kyll
  • 7,036
  • 7
  • 41
  • 64
  • Awesome @kyll, lemme go through this and get back to you – Guns Aug 06 '15 at 21:06
  • @Guns If you didn't know a lot about Meteor and reactivity and `Tracker` and subscription handling before, then it will be a lot to go through! – Kyll Aug 06 '15 at 21:08
  • Thanks @kyll, yes, i am a newbie to meteor and this is my first project and am stuck on the login screen :( – Guns Aug 06 '15 at 21:11
  • 1
    @Guns Well you are exploring a completely unknown and quite special territory, so I would suggest sticking to the examples and tutorials given by Meteor and some nice blogs (older articles on [MeteorHacks](https://meteorhacks.com/) or [the DiscoverMeteor blog](https://www.discovermeteor.com/blog/)) – Kyll Aug 06 '15 at 21:18
1

console.log is asynchronous for objects, in the sense that it's only logging a reference, which is evaluated the moment you click on it to expand. (It's interesting to note that the first line, however, is capturing the current state of the object at the time of the log call, as pointed out by Bergi in the comments)

So what's probably happening here is that some asynchronous function is adding property 0 to data between the time of logging and you opening the object in the console.

See, for example, this answer and discussion on the topic.

Community
  • 1
  • 1
doldt
  • 4,466
  • 3
  • 21
  • 36
  • 1
    In fact the first line of the object is a synchronous capture at the moment of logging, and it indeed shows that the array has no `0` property. – Bergi Aug 06 '15 at 20:32