I need to be able to change some variable's value, when app is closed.
I'm using exitEvent described here:
https://docs.nativescript.org/core-concepts/application-lifecycle
Also, i'm using local-storage plugin that works similar to javasctip's localstorage.
https://github.com/NathanaelA/nativescript-localstorage
My simple code looks like this:
var Observable = require("data/observable").Observable;
require("nativescript-dom");
var LS = require("nativescript-localstorage");
const application = require("tns-core-modules/application");
var page = require("ui/page");
exports.load = function (args) {
var page = args.object;
var model = new Observable();
var frame = require('ui/frame');
var ff = frame.getFrameById("dashboard");
var topmost = frame.topmost();
// This is exit event
application.on(application.exitEvent, (args) => {
LS.setItem('XX','111')
});
// What i will exit app, and run app again this will newer become 111,
it's null all the time
console.log(LS.getItem('XX'));
}
So, my question is - is possible to set any flag on app exit - it do not have to be localstorage (i've tested global variables to), to detect if exit was made, and based on this i can make a decisions that will help me ?
One of scenarios may be - i'm holding some flag in Localstorage that is TURE is user tapped "rememebr me" on the login screen.
So on exit i can check if he want's to be rememebered, if not i want to send user to login page and not dashboard when app is lauching....
Thank you.
EDIT:
I've tried applications-settings too, it will not work.
application.on(application.exitEvent, (args) => {
applicationSettings.setString("Name", "John Doe");
});
console.log(applicationSettings.getString("Name")); // not working
I suspect it's the issue with the nativescript-localstorage plugin. It writes the changes to file after a 250ms delay. At exit event you will give you very limited amount of time before your app is completely killed by system.
May be the Author had a reason for setting up this delay but I think its too much of time at least in this particular scenario so the changes are never written to file. You may raise a issue at the plugin's Github repo.
If you are looking for an immediate workaround, copy localstorage.js to your app and export internalSaveData from the file, so you could directly call it right after you finish setting your values.
Related
I have just tried Optimizely. The problem is it will show different variations to a user. Sometimes we don't expect this behaviour. For example if I change color to red from blue, Optimizely will randomly select between the orginal (blue) and the variation (red) for the same user which is inconsistent. How can I make Optimizely to always show the same variation to a user?
Place the following code in your Experiment JavaScript:
setCookie = function (c_name,value,exdays) {
var exdate=new Date();
exdate.setDate(exdate.getDate() + exdays);
var expires = exdate.toUTCString();
var isIE8 = (document.documentMode !== undefined);
if (exdays == 0) {
expires = (isIE8 == true) ? "" : "0";
}
var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+expires);
document.cookie=c_name + "=" + c_value;
}
Within each variant (e.g. Blue Variant, Red Variant, etc.), call setCookie and check whether the cookie exists for a user in that particular variant. If the cookie does exist, then run whatever code you want that particular variant to run. Below is an example of setting a cookie called tester that will expire after 30 days.
setCookie('tester',true,30);
if(document.cookie.indexOf('tester')>-1){
//RUN YOUR CODE HERE IF THIS VISITOR HAS THIS COOKIE
}
Hi there I am an engineer at Optimizely,
You could alternatively try the Fullstack product, which is more developer-oriented. With this you get an SDK that you install with your bundle and you implement your testing logic using code.
Example:
npm install optimizely-client-sdk
const optimizely = require('optimizely-client-sdk');
const optimizelyClient = optimizely.createInstance({
datafile: {} // this is your experiment config which you get from the Optimizely UI
});
const variation = optimizelyClient.activate('color_experiment', 'user_1');
if (variation === 'blue') {
// do something for blue
} else if (variation === 'red') {
// do something for red
} else {
// default case
}
And as long as you pass in the exact same user_id as the second argument to activate, you are guaranteed to always get the same variation for that user.
For more information or details on getting started please take a look at: https://developers.optimizely.com/x/solutions/sdks/getting-started/index.html?language=javascript
Also keep in mind that Optimizely gets blocked by adblockers, it can happen if a user turns their adblocker on after they've been on the page and served up an experiment to see - they would get the original version.
(sorry for my bad english)
I have a big problem with which I've been beating me for several days but to which I do not find any solution, even while going to excavate very far in subjects on known forums (and less known).
I develop a small application in Javascript which must recover an array of links. I open these links one by one in the same page, and I click on a button (which posts a name), then I check after a small lapse of time that the name is well posted and corresponds to that present on the page (in a fixed div). At this time, I turn over on the basic page, then I start the script again with the second link contained in the array.
The problem is that the code is not carried out anymore after the window.load() function.
I test the code on Google Chrome (in the Javascript console) and it turns over me an error: “Uncaught ReferenceError: init is not defined … onload ".
I hope that you will be able to help me to find how to once carry out the code with the launching of the page it is launched since each bond opens a page in the relationship page.
Before, I had tested in a popup with the function window.open () (without “_parent”) and I wanted to close it thanks to window.close () function, but the code did not include/understand where to act since the remainder of the code was to now deal with the popup and not of the page on which the code was carried out at the beginning.
Here's the code :
//Here i get the links in an array
function recupHref(){
var lesHref = new Array();
var lesLiens = document.getElementsByTagName("a");
for(var i = 0; i < lesLiens.length; i ++)
if(lesLiens[i].parentNode.getAttribute("class") == "pubrhead-text-right")
lesHref.push(lesLiens[i].getAttribute("href"));
return lesHref;
}
var resultat = recupHref(); //I store them in a variable
//The main function which open the links one by one
//The while loop allows us to know if were subscribed or not
var o = function openLinks(){
for(var leIndex = 0; leIndex < resultat.length; leIndex ++){
window.open(resultat[leIndex], "_parent");
//Do i use window.load instead of DOMContentLoaded ?
addEventListener("DOMContentLoaded", function() {
document.getElementById("enbut").click();
var pseudo = document.getElementById("nameho").innerHTML;
var pseudok = document.getElementsByClassName("pname")[0].textContent;
});
while (pseudo === pseudok) {
!(window.open("http://page-with-links.html", "_parent"));
};
}
}
I thank you in advance, and I hope that you will include/understand my problem.
Here is a little draw to explain better than words :
In other words, just what i need is that : store links (done) --> Open the link --> Click on the button (done) --> Check if the 2 names are the same --> Came back to the first page/close popup/ (or go directly to the seconde link in the array) --> do this for the 2nd link, etc, etc.
Good day/evening.
I have some code and the result of it depends on the current time. Say,
Shop.prototype.isOpen = function() {
var now = new Date();
var today = now.getDay();
return this.openTime(today) <= now && now <= this.closeTime(today);
};
And then in the view, we display whether a shop is open:
<span ng-show="shop.isOpen()">Open now!</span>
The isOpen method is called once and doesn't get updated after that.
I have lots of complex application logic that depends on the isOpen and similar "time-bound" data.
What are the general approaches to keep the isOpen data fresh and have application logic/view be constantly in sync with that?
I think one solution would be to have an intermediate object whose value gets updated in frequent intervals, but I'm not sure if this is the right approach.
The angular documentation on directives has an example of time being updated.
http://docs.angularjs.org/guide/directive
But basically, have your controller set a $scope (or $rootScope, depending on how you want to access it) property that gets updated via a setTimeout loop.
Since extensions can not access unsafeWindow, like Firefox can, to hook into DOM scripts am I looking for other ideas so I come to SO for help!
How about using some code to inject into DOM and sending the intercepted response to a background page, which then does some initial processing before calling a content script for final processing. When done, it answers to the background with a modified response, or the original (it depends), and the background page sends the response back to DOM which handles it to the DOM script response function.
There is just one problem with this, a background page cant communicate with the DOM.
I did a small test with injecting some code, where I output something to the console and an alert. The result wasnt good, as the alert fired but the console was empty - not even an error, which makes me wonder - what console received the output ?
function injectCode(fn){ // Executing an anonymous script
var script = document.createElement('script');
script.type = 'application/javascript';
script.textContent = '(' + fn + ')();';
document.documentElement.appendChild(script); // run the script
document.documentElement.removeChild(script); // clean up
}
var code = function(){
console.log('dom',window);
alert('code injected');
}
injectCode(code);
I also tried addEventListener, with DOMAttrModified DOMSubtreeModified DOMNodeInserted, on DOM elements that change when the DOM ajax response is fully parsed but all failed to fire.
Am I trying to do the impossible, by any means ?
Before continuing, make sure that you know the differences between the script contexts in an extension.
To inject a script from the background page, you have to execute a Content script, which on his turn injects the script as mentioned in your question / here.
Examples (using chrome.tabs.executeScript):
// null = current active tab
// Simple code, background:
chrome.tabs.executeScript(null, {
code: [
'var s = document.createElement("script");',
's.textContent = "console.log(window);";',
'(document.head||document.documentElement).appendChild(s);',
's.parentNode.removeChild(s);'
].join('\n')
});
I can imagine that this method is not doable for a big chuck of code. For a set of pre-defined scripts, you can then use two scripts: the code itself, and a helper script:
// config.js
var fn_code = function() {
console.log(window); ....
};
// helper.js
var s = document.createElement('script');
s.textContent = '(' + fn_code + ')();';
(document.head||document.documentElement).appendChild(s);
s.parentNode.removeChild(s);
// Background:
chrome.tabs.executeScript(null, {file: 'config.js'}, function() {
chrome.tabs.executeScript(null, {file: 'helper.js'});
});
Note: I did not directly link to "config.js", because that complicates the use when using manifest version 2, see "web_accessible_resources".
The previous method only shows how to execute code in one direction (background -> page). If there's a need to activate a background's function from the injected script, you have to define and listen to a custom event handler. See this answer + demo.
Because the code is injected, thus runs in the scope of the page, you have to check the console at the page.
When chrome.tabs.executeScript fails to execute the Content script (eg. because the extension does not have the permission to access a certain page), an error is logged at the console in the background page. This console can be accessed by following these steps.
I want to track a variable as I navigate around my site. How can I use jQuery to output this value without having to worry about tracking down wherever it might be affected and having it update.
var num = 1;
$(#trackvariable).text(num)
I want the above to execute constantly as it were.. I don't necessarily want to do it on a timer. Is there any way to do that?
If you want to listen to changes on a textnode, you can do something like this:
function InitListener () {
var container = document.getElementById ("textContainer");
var textNode = container.firstChild;
if (textNode.addEventListener) {
textNode.addEventListener ('DOMCharacterDataModified', OnCharacterModified, false);
}
}
This will only work in Firefox (and probably Chrome in Safari also):
https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects#Defining_Getters_and_Setters
Off the top of my head I would say that the functions changing the variable should just call some sort of update function at the end of them? just an idea. I think even if you set up some kind of custom event it would still have to manually triggered in each function.