dojo 1.7+ timer/setInterval misunderstanding - function

I have a javascript code that creates a simple clock.
define([
"dojo/_base/declare",
"dojo/dom",
"dojo/date/locale",
"dojo/_base/event"
],
function(declare, dom, locale, event) {
return declare([], {
...
...
createClock : function() {
html_time = dom.byId("time");
window.setInterval(this.tick(), 1000);
}
});
});
JS code is working correctly! Also, I have a html code:
<body>
<script>
require([ "gui/common/Clock"
],
function(Clock) {
var clock = new Clock();
clock.createClock();
});
</script>
Current time: <span id="time"></span>
...
But if I run the code in the browser, then I get an error:
Error: useless setInterval call (missing quotes around argument?)
[Break On This Error]
window.setInterval(this.tick(), 1000);
In the browser the time appears, but it does not tick. Anybody can explain what is my problem?

Do not execute the method: window.setInterval(this.tick, 1000);
Also to execute tick in this scope, use lang.hitch as of dojo/_base/lang module:
window.setInterval(lang.hitch(this, "tick"), 1000);
You can find some inspiration in my answer to How to do something while a dojo xhr request is waiting or loading.

Related

Polymer Web Component Tester sendKeys

Is there a method that I can use to send keys to an input field using web component tester? I'd like to test sending the return key to a form.
I'm not aware of such a method in Web Component Tester, but Polymer's iron-test-helpers has MockInteractions that can send keys to a target. It even has one specifically for ENTER: MockInteractions.pressEnter(target).
Install
bower i --save-dev iron-test-helpers
Usage
<link rel="import" href="iron-test-helpers/iron-test-helpers.html">
<script>
describe('accessibility', function(done) {
it('should jump to next page on ENTER key', function() {
var el = fixture('basic');
var expectedIndex = el.pageIndex + 1;
MockInteractions.pressEnter(el.$.nextBtn);
// pressEnter() simulates key-down and asynchronous key-up,
// so wait a while before testing the result
setTimeout(function() {
expect(el.pageIndex).to.be.eql(expectedIndex);
done();
}, 500);
});
});
</script>

HTML5 File upload with AngularJS

I'm trying to get angular to read the contents of a file that the user selects through an <input type="file" control. Even though angular does not have directives for file upload controls, it should be easy to fix that with a call to $apply:
function MyController($scope) {
$('#myFile').on('change', function() {
var that = this;
$scope.$apply(function() { $scope.files = that.files });
});
}
Unfortunately, the event is never fired. It's like the selector is unable to refer to the correct DOM element: even though the selector finds the element, the list of files is always empty. This also happens if i poke around with the js console. The DOM inspector instead has the file list among its properties.
It's driving me crazy, but the only way I've got it to work so far is to use an inline event handler that assigns to a global variable. Why is the jquery selector returning another item? Is there some template compilation mumbo-jumbo that angular does which confuses selectors?
Here is what I do:
http://plnkr.co/edit/JPxSCyrxosVXfZnzEIuS?p=preview
app.directive('filelistBind', function() {
return function( scope, elm, attrs ) {
elm.bind('change', function( evt ) {
scope.$apply(function() {
scope[ attrs.name ] = evt.target.files;
console.log( scope[ attrs.name ] );
});
});
};
});
template:
<input type="file" filelist-bind name="files"/>
<p>selected files : <pre>{{ files | json }}</pre></p>
This kind of task, you definitely want to make use of directive.
But I think that your main concern is how to access the selected file
objects and my example should clarify that.
If you are looking for file upload with angular you can use this plugin
https://github.com/danialfarid/angular-file-upload
It is basically a directive like tosh's answer that takes care of non-HTML5 browsers with FileAPI flash polyfill and has $http.uploadFile function to upload the actual file via AJAX.
This site uses Angular service for HTML5 File Upload. A simple way is to setup a controller which calls the service and updates the UI when the asynchronous call is completed.
controller:
myapp.controller('fileUploadCtrl', ['$scope', '$q', 'FileInputService', function ($scope, $q, FileInputService) {
$scope.fileInputContent = "";
$scope.onFileUpload = function (element) {
$scope.$apply(function (scope) {
var file = element.files[0];
FileInputService.readFileAsync(file).then(function (fileInputContent) {
$scope.fileInputContent = fileInputContent;
});
});
};
}]);
service:
myapp.service('FileInputService', function ($q) {
this.readFileAsync = function (file) {
var deferred = $q.defer(),
fileReader = new FileReader(),
fileReader.readAsText(file);
fileReader.onload = function (e) {
deferred.resolve(e.target.result);
};
return deferred.promise;
};
});
template:
Choose File <input type="file" onchange="angular.element(this).scope().onFileUpload(this)">
<br />
{{fileInputContent}}
Reference: You can find the full source code and reference on this site.

Is is possible to catch if the creation of a web worker if failing?

In the example below there is in an error in the code for the web worker (undefined reference) but try { ... } catch(e) { ...} does not catch much. The message Why am I here ? appears on the console.
HTML file:
<html>
<body>
<script type="text/javascript">
var worker;
try {
worker = new Worker("foo.js");
console.log('Why am I here ?');
} catch (e) {
console.log('Error creating the worker.');
}
// No matter what, an object "worker" will created during the call to Worker()
// How to test that all went well
var worker_failed = false;
worker.addEventListener("error",
function(e) { worker_failed = true },
false);
// Is it correct to assume that "worker" is created asynchronously, and that checking
// that creation went well should not be sequential and the test below is not
// the way to do it ?
if ( worker_failed ) {
// Worker("foo.js") failed, switch to plan B
}
</script>
</body>
</html>
Web worker (foo.js):
foobar = 2 + baz; // fails here (baz is undefined)
onmessage = function(e) {
var data = e.data;
postMessage(data);
};
You can handle errors in your workers asynchronously. You need to listen to the error event of the worker.
worker.addEventListener("error", onError, false);
There's a great tutorial about web workers here. You can find exactly what you're looking for in the handling errors section.
You can also check the official html5 spec for more information about how this should be implemented by the browsers.

dojo 1.8 integrating html5 postmessage

Im trying to get some html5 post messaging going with dojo 1.8, i've created a jsfiddle to try to explain it better. One thing to note is that the button is being loaded within the iframe. So basically if a click happens within the iframe then the parent node should receive and act upon the message. Any pointers would be appreciated.
http://jsfiddle.net/AvPFv/
Basically, you should listen for message on iframe window, i.e. iframe.contentWindow. Also, please note there is no dojo in your iframe.
I created a jsFiddle to show how it works: http://jsfiddle.net/phusick/H7Zh8/ but I'm afraid it is very messy to have everything in a single file, i.e. in the context of the parent window, because it does not explain properly where window reference points to and it does not simulate real world usage. I suggest you try it at localhost having two sets of scripts, one for parent window and one for iframe.
require([
"dojo/dom",
"dojo/on",
"dojo/date/locale",
"dojo/domReady!"
], function(
dom,
on,
locale
) {
var buttonNode = dom.byId("postMessageButton");
var iframeNode = dom.byId("iframe");
var iframe = iframeNode.contentWindow;
var iframeButtonNode = iframe.document.getElementById("postMessageButton");
on(buttonNode, "click", function() {
iframe.postMessage("hello from parent", "*");
});
on(iframe, "message", function(event) {
var msgNode = iframe.document.getElementById("msg");
msgNode.innerHTML += formatMessage(event);
event.source.postMessage("echo from iframe", "*");
});
on(iframeButtonNode, "click", function() {
iframe.parent.postMessage("hello from iframe", "*");
})
on(window, "message", function(event) {
dom.byId("msg").innerHTML += formatMessage(event);
});
function formatMessage(event) {
var time = locale.format(new Date(event.timeStamp),{
selector: "time",
formatLength: "medium"
});
return time + ": " + event.data + "<br>";
}
});

delay or setInterval in mootools

Good morning,
I have a problem with mootools, and I make an alpha effect from 0 to 100 but I would like to make a delay before loading the next effect.
code is as follows:
<script type="text/javascript">
var miEfecto1 = new Fx.Style('texto42' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto2.start(1,0) , 15000 );}});
var miEfecto2 = new Fx.Style('texto14' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto3.start(1,0) , 15000 );}});
...etc...
var miEfecto59 = new Fx.Style('texto45' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto60.start(1,0) , 15000 );}});
var miEfecto60 = new Fx.Style('texto39' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto61.start(1,0) , 15000 );}});
window.addEvent('domready',function() {
miEfecto1.start(1,0);});
</script>
thank you very much for your help!
setInterval sets interval for some function you pass as the first parameter, where setTimeout just delays the execution. Use the latter to avoid multiple execution.
Also in your code you immediately execute start() method (eg. miEfecto2.start(1,0)), because you do not pass it - you pass its result. To fix this you can enclose it in an anonymous function (but do not call it).
The example code could look like this (notice setInterval being replaced by setTimeout and that I enclosed the function call in anonymous function):
var miEfecto1 = new Fx.Style('texto42', 'opacity', {
duration: 9000,
onComplete: function(){
setTimeout(function(){
miEfecto2.start(1,0);
}, 15000);
}
});
Make similar changes in the rest of your code.
what you need to do is to chain the effects and set the delay to whatever you need..
check this example : http://demos111.mootools.net/Chain
or check the doc : http://mootools.net/docs/core/Class/Class.Extras
Hope this helps
THE SOLUTION:
var miEfecto_i1 = new Fx.Style('texto19', 'opacity', {
duration: 1000,
onComplete: function(){
setTimeout(function(){
miEfecto_o1.start(1,0);
}, 10000);
}
});
var miEfecto_o1 = new Fx.Style('texto19', 'opacity', {
duration: 1000,
onComplete: function(){
miEfecto_i2.start(0,1);
}
});
THANKS!!