Add/Update parameter for a Context - dialogflow-es

In Dialogflow fulfillment I am trying to add or update parameters for a context.
let currentContext = agent.context.get('setupcall-followup');
console.log(agent.context.get('setupcall-followup').parameters); //1
currentContext.parameters.date = '2019-09-18T12:00:00-04:00';
currentContext.parameters.time = '2019-09-17T13:00:00-04:00';
currentContext.parameters['Test'] = 'Test';
console.log(agent.context.get('setupcall-followup').parameters); //2
agent.context.set(currentContext); //Seems to not be needed, since it is by reference
console.log(agent.context.get('setupcall-followup').parameters); //3, same as #2
By #2 & #3 the log shows that it was updated.
But in the Diagnostic Info > Raw API Response, the outputContext information is still the original inputContext, before modification.
What I can do:
Add a new context, with it's own parameters.
What I can't do
Get a context & change a parameter

This is the only way I finally got it to work.
Use a custom context & recreate it completely, every-time.
FYI Code below requires lodash for _.merge
function getSessionData() {
if(agent.context.get('session_details')) {
return agent.context.get('session_details').parameters.sessionDetails;
} else {
return;
}
}
function setSessionData(data) {
if(agent.context.get('session_details')) {
let session = agent.context.get('session_details').parameters.sessionDetails; //Extract the data from the existing "session_details" context
_.merge(session, data); //Update our data
let sessionContext = { //Define the complete context object again
name: "session_details",
lifespan: 5,
parameters: {
sessionDetails: session
}
}
agent.context.set(sessionContext);
} else {
let sessionContext = { //Define the complete context object again
name: "session_details",
lifespan: 5,
parameters: {
sessionDetails: data
}
}
agent.context.set(sessionContext);
}
}

I think this may help.
const parameters = {'param1':value, 'param2': value};
agent.context.set(context, 5, parameters); //here "5" is lifespan.
Tell me if it worked.

Related

ReferenceError - Context is not defined (Netsuite)

I am trying to hide a field when a checkbox is checked in an Opportunity but the script I have is throwing a ReferenceError - Context is not defined.
Here is my code:
define(['N/currentRecord','N/search', 'N/format'],
function(currentRecord, search, format) {
function pageInit_disableMyText(scriptContext) {
console.log('START : here you will be able see logs via console (F12 on browser)');
var recCurrent = context.currentRecord; //This represents your current loaded record, you can get the values of the fields here
var myCheckbox = recCurrent.getValue('custbody7'); //This is the code for getting the value of your field
console.log('myCheckbox Value is : ' + myCheckbox);
if(myCheckbox == true)
{
//get the field and disable it
fld1 = recCurrent.getField('custbody3');
fld1.isDisabled = true;
}
else
{
//if you didn't set the field to be disabled by default, then you don't need the code to enable it here
//since it runs only once when the page loads
}
}
function fieldChanged_toggleBox(scriptContext) {
//Different function that triggers on change of a field value, can use this to toggle the checkbox
var currentFieldID = context.fieldId;
console.log('context.fieldId : '+ currentFieldID);
//Check which field is toggled
if(currentFieldID == 'custbody7')
{
//Essentially do the same as above
var recCurrent = context.currentRecord;
var myCheckbox = recCurrent.getValue('custbody7');
if(myCheckbox == true)
{
//get the field and disable it
fld1 = recCurrent.getField('custbody3');
fld1.isDisabled = true;
}
else
{
//Now you need code to enable it as you are toggling the disabling and enabling it realtime
fld1 = recCurrent.getField('custbody3');
fld1.isDisabled = false;
}
}
}
//this is the retrun statement where we declare the script type to implement
return {
pageInit: pageInit_disableMyText,
fieldChanged: fieldChanged_toggleBox
};
});
When I use devtools in Chrome it shows the error on this line:
var recCurrent = context.currentRecord; //This represents your current loaded record, you can get the values of the fields here
But I cannot see what the problem is.
Any help is appreciated.
Thanks!
The parameter name in your function is scriptContext , change it to context
function pageInit_disableMyText(scriptContext) { // <---- Change this parameter to context
Basically you can call it whatever you like, but then you have to use the same variable.

passing function to a class in nodejs

I have a function that I need to pass to a class I have defined in nodeJs.
The use case scenario is I want to give the implementer of the class the control of what to do with the data received from createCall function. I don't mind if the method becomes a member function of the class. Any help would be appreciated.
//Function to pass. Defined by the person using the class in their project.
var someFunction = function(data){
console.log(data)
}
//And I have a class i.e. the library.
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall(){
var result = new Promise (function(resolve,reject) {
resolve(callApi());
});
//doesn't work. Keeps saying notificationHandler is not a function
result.then(function(resp) {
this.notificationHandler(resp);
}) ;
//I want to pass this resp back to the function I had passed in the
// constructor.
//How do I achieve this.
}
callApi(){ ...somecode... }
}
// The user creates an object of the class like this
var obj = new A("abc#gmail.com", someFunction);
obj.createCall(); // This call should execute the logic inside someFunction after the resp is received.
Arrow functions (if your Node version supports them) are convenient here:
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall() {
var result = new Promise(resolve => {
// we're fine here, `this` is the current A instance
resolve(this.callApi());
});
result.then(resp => {
this.notificationHandler(resp);
});
}
callApi() {
// Some code here...
}
}
Inside arrow functions, this refers to the context that defined such functions, in our case the current instance of A. The old school way (ECMA 5) would be:
createCall() {
// save current instance in a variable for further use
// inside callback functions
var self = this;
var result = new Promise(function(resolve) {
// here `this` is completely irrelevant;
// we need to use `self`
resolve(self.callApi());
});
result.then(function(resp) {
self.notificationHandler(resp);
});
}
Check here for details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

Sending extra parameters to handler

Basically I have this
CSGOCli.playerProfileRequest(CSGOCli.ToAccountID(userId));
But I want some extra information I want in the event listener. So I thought I could change it to this:
CSGOCli.playerProfileRequest(CSGOCli.ToAccountID(row.steam64ID), "checkRank", myData[0]);
This is the event listener right now:
CSGOCli.on("playerProfile", function(profile) {
So I'm guessing it would have to look like this:
CSGOCli.on("playerProfile", function(profile, eventType, userData) {
Now the handler that handles these functions is this:
CSGO.CSGOClient.prototype.playerProfileRequest = function(accountId, even_type, my_data req_level, callback) {
callback = callback || null;
if (!this._gcReady) {
if (this.debug) {
util.log("GC not ready");
}
return null;
}
if (this.debug) {
util.log("Sending player profile request");
}
var payload = new protos.CMsgGCCStrike15_v2_ClientRequestPlayersProfile({
account_id: accountId,
request_level: req_level || 32
});
this._gc.send({msg:CSGO.ECSGOCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile, proto: {}}, payload.toBuffer(), callback);
};
var handlers = CSGO.CSGOClient.prototype._handlers;
handlers[CSGO.ECSGOCMsg.k_EMsgGCCStrike15_v2_PlayersProfile] = function onPlayerProfileResponse(message) {
var playerProfileResponse = protos.CMsgGCCStrike15_v2_PlayersProfile.decode(message);
if (this.debug) {
util.log("Received player profile");
}
this.emit("playerProfile", playerProfileResponse, eventType, userData);
};
Like you can see, in the last line "this.emit" I already changed how I want it to look but now this is the place where my problem comes. How could I edit this handler so in the last emitter it would send my info from the last function.
I'm sorry if I'm being unclear here.
EDIT:
Solved by just using global variables.
So:
var event_type = null;
var myData = null;
Without editing the handler.
and then set the variables in the function and later you can use it in the event listener.
Not a very pro-efficient solution, but it worked for me.

Node + ES6 classes: Setting up a set of cached objects

I've tried to search for instance caching and singletons on Google and StackOverflow without success, seeing only posts about module.exports, if you know a post that answers this question, feel free to reference it. Thank you!
I have an application that needs to work on a set of objects that rarely change, and hence need to be cached for performance optimisation.
Here is a toy example where a single property is set directly.
When I call the application, I export an object that will contain the set of cached objects in assets_cached.js:
const Assets = {};
module.exports.Assets = Assets;
In another module of the application I have an ES6 class:
const _ = require('lodash')
const { Assets } = require('./assets_cached')
class Asset {
constructor(id, some_property) {
if (id in Assets) {
// Update instance data with cached properties
_.assign(this, Assets_cached[id]);
} else {
// If it's not cached, create a new object
this.id = id;
this.some_property = some_property;
// Cache this object
Assets_cached[id] = this;
}
}
getProperty() {
return this.some_property;
}
setProperty(value) {
this.some_property = value;
// Is there a way of avoiding having to do this double assignment?
Assets_cached[id].some_property = value;
}
}
module.exports = Asset;
How may I avoid having to set the some_property twice (in the current instance and the cache, while ensuring that other instances are updated in parallel)?
Ideally I'd like to do something like:
if (id in Assets) {
this = Assets.cached[id]
}
inside the constructor, but this is not possible.
What's the most elegant and correct way of making this work?
Ideally I'd like to do something like this = Assets.cached[id] inside the constructor
The magic keyword here is return. You can just return an arbitrary object from the constructor and it will be used instead of this.
constructor(id, some_property) {
if (id in Assets) {
// use cached instance instead of creating a new one
return Assets_cached[id];
} else {
this.id = id;
this.some_property = some_property;
// Cache this object
Assets_cached[id] = this;
}
}
Here is the approach to the comment that was made some half an hour ago ...
const { Assets_cached } = require('./assets_cached');
// const { AssetStore } = require('./assetstore');
class Asset {
constructor(id, some_property) { // clean/lean constructor.
this.id = id;
this.some_property = some_property;
}
getProperty() {
return this.some_property;
}
setProperty(value) {
this.some_property = value;
}
}
function isAsset(type) {
// poor man's approach ... change to something more feasible.
return (type instanceof Asset);
}
function createAsset(id, some_property) { // factory that also handles caching.
var
asset = Assets_cached[id];
// asset = AssetStore.get(id);
if (!(asset && isAsset(asset))) {
asset = Assets_cached[id] = (new Asset(id, some_property));
// AssetStore.put(id, (asset = new Asset(id, some_property)));
}
return asset;
}
module.exports = {
create : createAsset,
isAsset : isAsset
};
Note
One also should consider providing a minimal API to Assets_cached, something like put/set, get and delete instead of Assets_cached being an entirely exposed, plain key-value store.

Javascript accessing object and array defined in modular function

This is a bit foreign to me and I'm probably not understanding it correctly. This is what I have:
var imgModule = (function() {
var imgLocations = {};
var images = [];
imgLocations.setImage = function(img, location) {
imgLocations[img] = location;
}
imgLocations.getImg = function(img) {
return imgLocations[img];
}
imgLocations.setImageArray = function(img) {
images.push(img);
}
imgLocations.getImageArray = function() {
return images;
}
return imgLocations;
}());
I want to be able to access the imgLocations Object and images array from outside this function. The setting functions work, but
document.getElementById("but").onclick = function() {
console.log(imgModule.imgLocations.getImageArray());
console.log(imgModule.imgLocations.getImg(imgName));
}
Both return "undefined". How do I access these variables? And how can I improve this function? Please be patient with me and explain what I'm doing wrong :) I'm trying to learn it the right way instead of defining a global variable outside all functions.
The reason why this isn't working, is because your imgModule is returning the imgLocations object. That being the case, imgModule will actually be the imgLocations object. So you would access your methods like so:
imgModule.setImage()
imgModule.getImg()
imgModule.getImageArray()
imgModule.setImageArray()
And as #gillesc stated. If you are wanting to keep the current syntax of imgModule.imgLocations.getImg() then you could return the imgLocations like so
return {
imgLocations: imgLocations
}
doing so would allow you to add more functionality to your module
return {
imgLocations: imgLocations,
otherObject: otherObject
}
...
imgModule.otherObject.someFunctionCall();
The problem is you are returning the object created and are not setting it as a property of an object.
So in your case this is how it would work.
document.getElementById("but").onclick = function() {
console.log(imgModule.getImageArray());
console.log(imgModule.getImg(imgName));
}
What you need to do is return it like this
return {
imgLocations: imgLocations
}
If you want the API you are attending to create and still have access to the array which you can not do currently.
You don't access imgModule.imgLocations, since what you return is imgLocations, you should access them as:
document.getElementById("but").onclick = function() {
console.log(imgModule.getImageArray());
console.log(imgModule.getImg(imgName));
}
It seems you try to write module pattern.
For deep understanding, I recommend you following article:
The Module Pattern, by Addy Osmani
and pay attention to example with counter:
var testModule = (function () {
var counter = 0;
return {
incrementCounter: function () {
return counter++;
},
resetCounter: function () {
console.log( "counter value prior to reset: " + counter );
counter = 0;
}
};
})();
// Usage:
// Increment our counter
testModule.incrementCounter();
// Check the counter value and reset
// Outputs: counter value prior to reset: 1
testModule.resetCounter();

Resources