Polymer: Call a behavior's property function in elements property values? - properties

Recently I looked up Polymers app-localize-behavior and I saw they typed the localize() method as Function (see on GitHub):
excerpt from app-localize-behavior.html:
localize: {
type: Function,
computed: '__computeLocalize(language, resources, formats)'
},
This method works perfectly fine in data-bindings, like <div>{{localize('welcome')}}</div>, but how can I call this method from my elements properties? I try to do something like:
excerpt from my-element.html:
properties: {
_pageTitle: {
type: String,
value: this.localize('welcome')
}
}
But when I try this, I get a Uncaught TypeError: this.localize is not a function. Even in my ready method I need to call this.localize asynchronously as otherwise it isn't defined, too.
How could I solve that problem?
Thank you in advance!

Use a computed property that invokes localize(...):
properties: {
_pageTitle: {
computed: 'localize("welcome")'
}
}
demo

Related

How do I emit multiple arguments via setup()?

I have the following function being passed as an emit to the component:
setTray(tray, pk) {
alert(tray)
alert(pk)
},
Calling inside a component, I am able to reach the function, but not the arguments:
setup(props, ctx) {
ctx.emit('setTray', 'profile-task', pk)
ctx.emit('setTray', {tray: 'profile-task', pk: pk})
}
Both approaches result in the arguments being undefined when setTray() is executed. What is the correct syntax in this situation?
The emit function accepts one or two arguments, the event name and the payload which in your case should be defined as object :
ctx.emit('setTray', {tray: 'profile-task', pk: pk})
in parent :
setTray({tray, pk}) {//destruct the payload
alert(tray)
alert(pk)
},
or in old way :
setTray(payload) {
alert(payload.tray)
alert(payload.pk)
},

What is the difference between returning an action vs returning the whole function in Page Object?

What is the difference between returning an action vs returning the whole function in Page Object?
this.download = function() {
element(by.id('modal-download-button')).click();
return this;
};
VS
this.download = function() {
return element(by.id('modal-download-button')).click();
};
Sometimes, to tackle timing and syncing issues, you want to explicitly resolve a promise returned by click(). In this case returning the "click" promise makes sense:
pageObject.download().then(function () {
// ...
});
Returning a full page object could be useful for chaining page object methods:
pageObject.download().get().verify();

How jasmine spy example works

All;
I am just starting learning Jasmine( version 2.0.3 ), when I got to Spies section, the first example confused me:
describe("A spy", function() {
var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar');
foo.setBar(123);
foo.setBar(456, 'another param');
});
it("tracks that the spy was called", function() {
expect(foo.setBar).toHaveBeenCalled();
});
it("tracks all the arguments of its calls", function() {
expect(foo.setBar).toHaveBeenCalledWith(123);
expect(foo.setBar).toHaveBeenCalledWith(456, 'another param');
});
it("stops all execution on a function", function() {
expect(bar).toBeNull();
});
});
I wonder if anyone could explain why the setBar function does not affect the bar defined inside describe block? How Jasmine spies deal with this?
Thanks
Because you are not actually executing the methods.
If you want this test to fail:
it("stops all execution on a function", function() {
expect(bar).toBeNull();
});
After these calls:
foo.setBar(123);
foo.setBar(456, 'another param');
Then you should call and.callThrough for your spy.
spyOn(foo, 'setBar').and.callThrough();
From the documentation
Spies: and.callThrough
By chaining the spy with and.callThrough, the spy will still track all
calls to it but in addition it will delegate to the actual
implementation.
With regard to your question, 'how jasmine deals with this?'
From here you can read a basic explanation:
Mocks work by implementing the proxy pattern. When you create a mock
object, it creates a proxy object that takes the place of the real
object. We can then define what methods are called and their returned
values from within our test method. Mocks can then be utilized to
retrieve run-time statistics on the spied function such as:
How many times the spied function was called.
What was the value that the function returned to the caller.
How many parameters the function was called with.
If you want all of the implementation details, you can check the Jasmine source code which is Open Source :)
In this source file CallTracker you can see how the gather data about the method calls.
A little more about the proxy pattern.

Dojo this.inherit throws 'Uncaught TypeError: Cannot read property 'callee' of undefined'

To facilitate a JsonRest store with a non-standard url scheme, I am trying to inherit JsonRest and override the _getTarget(id) function. Here is what my inherited javascript class looks like:
define([
"dojo/_base/declare",
"dojo/store/JsonRest",
],
function(declare, JsonRest) {
return declare(JsonRest, {
_getTarget: function(id){
var target = this.target;
if(typeof id != "undefined"){
if(target.indexOf("{id}") != -1) {
//use template
target = target.replace("{id}", id);
} else {
target = this.inherited(id);
}
}
return target;
},
});
});
However the line target = this.inherited(id); returns an error: Uncaught TypeError: Cannot read property 'callee' of undefined.
I looked at the docs, and I think I am doing it right:
http://dojotoolkit.org/reference-guide/1.10/dojo/_base/declare.html#calling-superclass-methods
What is the proper way to call the base class's _getTarget(id) function?
If you look closely the part of the documentation you linked, you are supposed to literally pass the arguments object to this.inherited - that's what contains the callee property it is looking for (and will include the id and any other arguments anyway, to be passed along to the superclass).
A few paragraphs in, the documentation also explains how to call this.inherited with arguments other than the same ones passed, if necessary: you can pass custom arguments in an array after arguments, i.e. this.inherited(arguments, [ ... ]). arguments always has to be first.

CameraCaptureUI.captureFileAsync fails to return IAsyncOperation object

For some reason, my code is unable to retrieve the IAsyncOperation object that is returned upon calling captureFileAsync method of the Windows.Media.Capture.CameraCaptureUI() method. The IAsyncOperation object is returned according to this documentation. In that documentation link, it states:
Return value
Type: IAsyncOperation<StorageFile>
When this operationcompletes, a StorageFile object is returned.
So here is my code:
var dialog = new Windows.Media.Capture.CameraCaptureUI();
var aspectRatio = { width: 4, height: 3 };
dialog.photoSettings.croppedAspectRatio = aspectRatio;
appSession.InAsyncMode = dialog.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo).done(function (file) {
if (file) {
self.addPage(URL.createObjectURL(file));
} else {
WinJS.log && WinJS.log("No photo captured.", "sample", "status");
}
}, function (err) {
// None taken
});
When I inspect the value of appSession.InAysncMode, I see that the function returns undefined. I suspect it returns undefined because the operation is not complete (i.e. the user has not yet created the photo, and it has not been saved to disc), but I need it in order to cancel out of the camera capture mode programmatically. Does anybody know why it would return undefined instead of the documented IAsyncOperation object?
Thanks!
For reference, here's the answer I posted on the MSDN forum.
To answer your ending question, you can cancel the capture UI by canceling the promise from dialog.captureFileAsync.
Your InAsyncMode flag is undefined because you're assigning to it the return value from captureFileAsync.done() which is, by definition, undefined. It has nothing to do with the API's success.
In the docs, when you see IAsyncOperation, what you get in JavaScript is a promise that will deliver as a result to the completed handler if it succeed. You never see IAsyncOperation or related interfaces in JavaScript directly. The documentation for WinRT is written to be language-neutral, so it's important to understand how those things show up in JS (as promises). In C# you don't see it either, as you just use the await keyword. It's mostly in C++ that you actually encounter the interface.
Anyway, you I believe you want is something along the lines of the code below, where you could eliminate IsAsyncMode in favor of just checking for a non-null promise:
appSession.capturePromise = dialog.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo);
appSession.IsAsyncMode = (appSession.capturePromise != null);
//This will close the capture UI after 5 seconds--replace with whatever logic you need
setTimeout(function () { appSession.capturePromise.cancel(); }, 5000);
appSession.capturePromise.done(function (file) {
if (file) {
} else {
}
}, function (err) {
appSession.IsAsyncMode = false;
appSession.capturePromise = null;
});