Cannot save in chrome Storage - google-chrome-extension

I use the following code to load and save a value in chrome.storage:
$(document).ready(function()
{
$( "#filterPlus" ).click(function()
{
SaveSwitch("plus1","#filterPlus","plus1");
});
}
function SaveSwitch(propertyName, imageId, imageSrc)
{
chrome.storage.sync.get(propertyName, function (result) {
var oldValue = result.propertyName;
alert('GET:old='+oldValue);
if (oldValue==null)
{
oldValue=false;
}
var newValue=!oldValue;
chrome.storage.sync.set({propertyName: newValue}, function()
{
alert('SET:'+newValue);
});
});
}
When I run through this method, the first alert shows:GET:old=undefined, the second alert shows:SET:true just like expected. But when calling that method again with the same parameters the first alert AGAIN shows GET:old=undefined instead of GET:old=true which I expected.
It is the same behaviour when I use storage.local instead of storage.sync
"storage" is in the manifest's permissions. The JS is called from the options-page of my extension-

You're doing .get("plus1", ...) and then later doing .set({"propertyName": newValue}, ...). You are storing under the key "propertyName" but fetching the key "plus1", which has never been set.
Perhaps your misunderstanding is that keys in object literals are themselves literal (even when not quoted), rather than variable identifiers. In that case, you might benefit form reading How to use chrome.storage in a chrome extension using a variable's value as the key name?.

Related

How to get entity from the argument and create if condition in Dialogflow Inline editor for fulfilment

I am completely new to Dialogflow and nodejs. I need to get the entity value from the argument to the function (agent) and apply if the condition on that. How can I achieve this?
I am trying below but every time I get else condition become true.
I have created an entity named about_member.
function about_member_handeller(agent)
{
if(agent.about_member=="Tarun")
{
agent.add('Yes Tarun');
}
else
{
agent.add("No tarun");
}
}
Please help.
In such cases, you may use console.log to help unleash your black box, like below:
function about_member_handeller(agent) {
console.log(JSON.stringify(agent, null, 2));
if(agent.about_member=="Tarun") {
agent.add('Yes Tarun');
}
else {
agent.add("No tarun");
}
}
JSON.stringfy() will serialize your json object into string and console.log will print the same on the stdOut. So once you run your code this will print the object structure for agent and after which you will know on how to access about_member. Because in the above code it's obvious that you are expecting about_member to be a string, but this code will let you know on the actual data in it and how to compare it.
To get the parameter you can use the following;
const valueOfParam = agent.parameters["parameterName"];

Botframework (Node) - dialogData stripping out regex

Does the BotBuilder Node SDK actively strip out anything that is stored the dialogData object?
For example, I have created a simple loop and I am storing a regex in session.dialogData.questions. When I console log this after storing it, I can see that my regex is stored as expected:
{
validation: /^[0-9]{19}$/,
}
However, when I try and log the same session.dialogData.questions object in the next step of my waterfall, then the regex seems to have been converted into an empty object:
{
validation: {}
}
I presume this a deliberate attempt to prevent XSS and other types of exploitation?
The code for this example can be found below:
const builder = require('botbuilder')
const lib = new builder.Library('FormBuilder')
lib.dialog('/', [
(session, args) => {
session.dialogData.questions = {
validation: /^[0-9]{19}$/
}
console.log(session.dialogData.questions)
builder.Prompts.confirm(session, 'Would you like to proceed?')
},
(session, results) => {
console.log(session.dialogData.questions)
}
])
module.exports.createLibrary = () => {
return lib.clone()
}
Regarding your initial question, no the SDK doesn't actively strip anything out of the dialogData object. Anything that is, except for regexp...
I'm not sure why this is, but for the time being I recommend storing your pattern as a string, '^[0-9]{19}$', and then constructing a new regexp via new RegExp(session.dialogData.questions.validation) when needed.
I tried storing a method to construct a new RegExp using this.questions.validation, but likewise this was also stripped out.
Edit:
Per Ezequiel's comment, this isn't a Bot Framework issue in the end. It is not possible to store non-serializable data inside JSON.

How to observe all object property changes?

For arrays I know you can do something like this:
function() {
}.observes("array.#each")
What I did was convert the object into an array and observe the properties with a #each, but is there a better way to observe object all property changes without converting it into an array?
You can observe isDirty to see if any of the object's values have been modified since last save (if you are using Ember Data).
Alternatively you can pass a comma separated list of properties to observes. This might be long if you have a lot of properties on your object, but will work.
A third approach could be to override setUnknownProperty() and set a property, a 'dirty flag' (or perform any action you may want in there.
There's also an old SO post that gives the following answer:
App.WatchedObject = Ember.Object.extend({
firstProp: null,
secondProp: "bar",
init: function(){
this._super();
var self = this;
Ember.keys(this).forEach(function(key){
if(Ember.typeOf(self.get(key)) !== 'function'){
self.addObserver(key, function(){
console.log(self.get(key));
});
}
});
}
});
You could probably split this out into a Mixin to keep your code DRY.
probably you could create something like a blabbermouth mixin and override the set method to get notified of property changes:
App.BlabbermouthMixin = Ember.Mixin.create({
set: function(keyName, value) {
this.set('updatedProperty', keyName);
this._super(keyName, value);
}
});
and observe the updatedProperty property?
You can get a list of properties in an object and apply them to a new property:
attrs = Ember.keys(observedObject);
var c = Ember.computed(function() {
// Do stuff when something changes
})
Ember.defineProperty(target, propertyName, c.property.apply(c, attrs));
Here is a working jsbin. Creating an observer instead of a property should be possible using a similar approach.

Run getter in javascript object defined by Object.setProperty()?

If I create an object property via Object.defineProperty() with a getter/setter method (an accessor descriptor) like:
var myObj = function myObj() {
var myFoo = 'bar';
Object.defineProperty(this, 'foo', {
enumerable: true,
get: function() {
return myFoo;
},
set: function(newValue) {
myFoo = newValue;
}
});
return this;
};
If I do something like var f = new myObj(); console.log(f) in Node, the output is something like:
{ foo: [Getter/Setter] }
console.log(f.foo) gets the proper 'bar' value, but is there a way to indicate that upon logging/inspecting, it should just run the getter and show the value?
First, it's important to understand why this happens. The logging functions don't run getters by design because your getter function could have side effects, whereas the logging function can guarantee that getting the value of a primitive doesn't.
When you pass an object to console.log, it's really just passing it off to the util module's inspect to format into human-readable text. If we look there, we see that the very first thing it does is check the property descriptor, and if the property has a getter, it doesn't run it. We can also see that this behavior is unconditional – there's no option to turn it off.
So to force getters to run, you have two options.
The simplest is to convert your object to a string before handing it off to console.log. Just call JSON.stringify(obj, null, 4), which will produce reasonably human-readable output (but not nearly as nice as util.inspect's). However, you have to take care to ensure that your object doesn't have any circular references and doesn't do something undesired in a toJSON function.
The other option is to implement a inspect function on your object. If util.inspect sees a function called inspect on an object, it will run that function and use its output. Since the output is entirely up to you, it's a much more involved to produce output that looks like what you'd normally get.
I'd probably start by borrowing code from util and stripping out the part about checking for getters.
This behavior is certainly intentional. I know I wouldn't want all the getter functions on an object running whenever I logged that object; that sounds like potential a debugging landmine, where debugging could alter the state of my program.
However, if indeed that is the behavior you want, you can add a new function:
Object.getPrototypeOf(console).logWithGetters = function(obj) {
var output = {};
var propNames = Object.getOwnPropertyNames(obj);
for(var i=0; i<propNames.length; ++i) {
var name = propNames[i];
var prop = Object.getOwnPropertyDescriptor(obj, name);
if(prop.get) {
output[name] = prop.get();
} else {
output[name] = obj[name];
}
}
// set output proto to input proto; does not work in some IE
// this is not necessary, but may sometimes be helpful
output.__proto__ = obj.__proto__;
return output;
}
This allows you to do console.logWithGetters(f) and get the output you want. It searches through an object's properties for getters (checking for the existence of Object.getOwnPropertyDescriptor(obj, propName).get) and runs them. The output for each property is stored in a new object, which is logged.
Note that this is a bit of a hacky implementation, as it doesn't climb the object's prototype chain.

How to add context helper to Dust.js base on server and client

I'm working with Dust.js and Node/Express. Dust.js documents the context helpers functions, where the helper is embedded in the model data as a function. I am adding such a function in my JSON data model at the server, but the JSON response to the browser doesn't have the function property (i.e. from the below model, prop1 and prop2 are returned but the helper property is not.
/* JSON data */
model: {
prop1: "somestring",
prop2: "someotherstring",
helper: function (chunk, context, bodies) {
/* I help, then return a chunk */
}
/* more JSON data */
I see that JSON.stringify (called from response.json()) is removing the function property. Not sure I can avoid using JSON.stringify so will need an alternative method of sharing this helper function between server/client. There probably is a way to add the helper functions to the dust base on both server and client. That's what I'm looking for. Since the Dust docs are sparse, this is not documented. Also, I can't find any code snippets that demonstrate this.
Thanks for any help.
send your helpers in a separate file - define them in a base context in dust like so:
base = dust.makeBase({foo:function(){ code goes here }})
then everytime you call your templates, do something like this:
dust.render("index", base.push({baz: "bar"}), function(err, out) {
console.log(out);
});
what this basically does is it merges your template's context into base, which is like the 'global' context. don't worry too much about mucking up base if you push too much - everytime you push, base recreates a new context with the context you supplied AND the global context - the helpers and whatever variables you defined when you called makeBase.
hope this helps
If you want stringify to preserve functions you can use the following code.
JSON.stringify(model, function (key, value) {
if (typeof(value) === 'function') {
return value.toString();
} else {
return value;
}
});
This probably doesn't do what you want though. You most likely need to redefine the function on the client or use a technology like nowjs.

Resources