User object misses data object


#1

I use skill with MongoDb user persistence. When I was testing my skill locally and assigning some data to the user data object to be persisted f.e.

this.$user.$data.locale = this.getLocale()

Everything was working fine, property got saved to the DB with other metadata I wanted.

But when I deployed my ‘skill’ to lambda it started saying:

Cannot set property 'locale' of undefined

After trying to log $user object it was apparent that $data object is missing. When I removed locale assignment I got:

Cannot read property 'createdAt' of undefined

For the lambda handler I use default one, that comes from the example skill.

As I said, when I test skill locally, using jovo debugger, everything works, but when I deploy it to lambda this happens. I guess there is a difference between this in lambda compared to locale environment or are there any other issues I should be aware of?


#2

Ok, so I tried just initialising new jovo skill hello world. The only thing that I changed is I added MongoDb package and replaced FileDb with it. I added connection string to configuration

db: {
    MongoDb: {
      databaseName: '<dbName>',
      collectionName: '<collectionName>',
      uri: '<connectionUri>',
    },

Then in project.js I added my lambda arn and deployed this skill using jovo cli deploy command.

I only changed these mentioned things, but now lambda just time-outs, no matter how much I increase its timeout.

Has anyone had any luck setting up mongoDb persistence on lambda?


#4

I resolved timeout issue by adding this flag to lambda handler function:
context.callbackWaitsForEmptyEventLoop = false

In regards to data object missing, when I put handlers right inside app.SetHandler function, it works fine, but when I import functions from another file, it doesn’t. I guess it has to do something with binding user data to this.

Tried exact example given in the docs, which talks about structuring app and putting handlers in their own files with hello world example and got same results.$data object is undefined in $user object.


#5

Hey @Rokas_Vaitkevicius,

could be a binding issue. How do you add the functions to your handler?


#6

I do it exactly as in docs. I added a new file called ‘launch.js’ which exports handler like this:

module.exports = function LAUNCH() {
    this.$user.$data.locale = this.getLocale();
    return this.ask(
      "Hello World! What's your name?",
      "Please tell me your name."
    );
  }

Then I require it in the app and add it as one of the handlers.

const LAUNCH = require('./launch')
app.setHandler({
    LAUNCH,
})

When I try printing console.log(this.$user.$data); In the handler, it is always undefined.


#7

Is this defined in general (or this.$user)? Or is it just the this.$user.$data that’s causing the problems?


#8

Other this functions that I used seem to be working. For example this.getLocale() works as expected. It seems that only this.$user.$data is broken. this.$user is also defined.


#9

Is your MongoDB accessable from your Lambda function? You don’t get any error, right?

Can you log the full data object for a given user id?

let data = await this.$app.$db.load('<USER_ID>');
console.log(data);

#10

Hmm, I get error ‘Cannot read property ‘load’ of undefined’. Also this.$app.$db is undefined too. So maybe it is not binding issue, but more of the mongoDb persistence adapter issue, I don’t know. Is there by any chance an example which works with mongo on lambda?


#11

I may have found the problem. Will try to fix it tomorrow :slight_smile:


#12

Could you update the jovo packages and try it again?

> jovo update

#13

Yep, it works now, thank you very much for your help :slight_smile:

Could you tell me what was the issue?


#14

Async…

The connection wasn’t established on the request.


#15

Should $data object be available in after.platform.init hook? Because it seems that it is missing there.

I thought that in this hook everything should be ready, but maybe I am mistaken. Maybe there is another place/hook/event where before picking the handler I could access $data object and save/retrieve some data from user object?


#16

It should be available after user.load. Here’s a list of all the middlewares: