Synchronous call to Rest API in polymer 2.0 - polymer-2.x

Can any body tell me as how to make synchronous calls to Rest services in polymer 2.0.
I am trying calculate client total balance which I can do only after receiving response from all below three Rest services.
Is there any way to synchronize them using some api e.g. Promise or anyother
<iron-ajax id="balanceAjax" url="/balances" last-response="{{res1}}"></iron-ajax>
<iron-ajax id="currencyAjax" url="/currencies" last-response="{{res2}}"></iron-ajax>
<iron-ajax id="rateAjax" url="/rates" last-response="{{res3}}"></iron-ajax>

You can have same observer function for all the three properties (res1,2 and 3) and in observer if all of them have some value then proceed and calculate the value.
res1: {
observer: 'responseChanged'
},
res2: {
observer: 'responseChanged'
}
res3: {
observer: 'responseChanged'
},
...
responseChanged: function() {
if(this.res1 && this.res2 && this.res3) {
//calculate total balance
}
}
You can also have one single observer instead of three
res1: {
},
res2: {
}
res3: {
},
...
observers: [responseChanged(res1, res2, res3)],
responseChanged: function() {
if(this.res1 && this.res2 && this.res3) {
//calculate total balance
}
}
Alternately, you can also use on-response listener of iron-ajax.
Lastly, if your res1 ,2 and 3 are expected to have value even before the api call you can set some booleans in on-response listener of each ajax and have observer on those booleans instead.

Related

Retrieve config value from sales channel in plugin settings

How can I retrieve values from the plugin config for a specific sales channel? I need to validate an API-Token, but can only retrieve the value stored for all sales channels and don't know how my custom admin component could even know about its current sales channel.
Currently, I am retrieving values via the following code, which follows the example plugin from Shopware, but they too only retrieve the global value.
Component.register('my-component', {
computed: {
getMyKey() {
return this.pluginConfig['MyPlugin.config.myKey'];
},
pluginConfig() {
let $parent = this.$parent;
while ($parent.actualConfigData === undefined) {
$parent = $parent.$parent;
}
return $parent.actualConfigData.null;
}
}
}
You may want to inject systemConfigApiService and use it to retrieve the config values. getValues takes a second argument for the sales channel id.
Component.register('my-component', {
inject: ['systemConfigApiService'],
methods: {
getConfig(salesChannelId) {
const values = this.systemConfigApiService
.getValues('MyPlugin.config', salesChannelId);
return values.myKey;
},
},
}

RxJava Flowable.Interval backpressure when flatmap with single

I'm having a scenario where I need to periodically call an API to check for a result. I'm using Flowable.interval to create an interval function which calls the API.
However, I'm having trouble with backpressure. In my example below, a new single is created on each tick in the interval. The desired effect is to only call the API if a call is not already in progress
Flowable.interval(1, 1, TimeUnit.SECONDS).flatMap {
System.out.println("Delay $it")
//simulates API call
Single.just(1L).doAfterSuccess {
System.out.println("NEW SINGLE!!!")
}.delay(4, TimeUnit.SECONDS).doAfterSuccess {
System.out.println("SINGLE SUCCESS!!!")
}.toFlowable()
}.subscribeOn(Schedulers.io()).observeOn(Schedulers.computation()).blockingFirst()
I can solve this using a filter variable like so:
var filter = true
Flowable.interval(1, 1, TimeUnit.SECONDS).filter {
filter
}.flatMap {
System.out.println("Delay $it")
Single.just(1L).doOnSubscribe {
filter = true
}.doAfterSuccess {
System.out.println("NEW SINGLE!!!")
}.delay(4, TimeUnit.SECONDS).doAfterSuccess {
System.out.println("SINGLE!!!")
filter = true
}.toFlowable()
}.subscribeOn(Schedulers.io()).observeOn(Schedulers.computation()).blockingFirst()
But it seems like a hacky solution. I've tired applying onBackPressureDrop after the interval function, but it has no effect.
Any suggestions?
You have to constrain flatMap as well:
Flowable.interval(1, 1, TimeUnit.SECONDS)
.onBackpressureDrop()
.flatMapSingle({
System.out.println("Delay $it")
//simulates API call
Single.just(1L).doAfterSuccess {
System.out.println("NEW SINGLE!!!")
}.delay(4, TimeUnit.SECONDS).doAfterSuccess {
System.out.println("SINGLE SUCCESS!!!")
}
}, false, 1) // <----------------------------------------------------------
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe()

How to check the dojo topic event is subscribed or unsubscribed

someMethod : function() {
if ( !this._evt ) {
this._evt = topic.subscribe("some-evt", lang.hitch(this, "_someOtherMethod"));
} else {
this._evt.remove();
//Here this just remove the listener but the object this._evt is not null
}
},
Here i just want to know how can we came to know that this class already subscribed to the 'some-evt'.
I don't want to set this._evt = null; to null after this._evt.remove();
Sorry, but the dojo/topic implementations typically do not provide a list of topics that have been published/subscribed to, and neither who published/subscribed to that topic. Dojo’s implementation conforms to this standard that there is no built-in mechanism to acquire a list of topics. Note that dojo/topic only have 2 functions, publish and subscribe.
You should implement your own idea, something like a mixin with a function to subscribe to a topic and keep a track of topic names registered, this is just an idea
The _TopicMixin.js
define(["dojo/topic"], function(topic){
return {
topicsIndex: {},
mySubscribe: function(topicName, listener){
this.topicsIndex[topicName] = topic.subscribe(topicName, listener);
}
myUnsubscribe: function(topicName){
if(this.topicsIndex[topicName]){
this.topicsIndex[topicName].remove();
delete this.topicsIndex[topicName];
}
}
amISubscribed: function(topicName){
return this.topicsIndex[topicName];
}
};
});
How you can use it
define(["dojo/_base/declare","myApp/_TopicMixin"], function(declare, _TopicMixin){
return declare([_TopicMixin], {
someMethod : function(){
if ( !this.amISubscribed("some-evt") ) {
this.mySubscribe("some-evt", lang.hitch(this, "_someOtherMethod"));
} else {
this.myUnsubscribe();
}
}
});
});
Hope it helps

Two-way filter updating on the fly | Vue.js

How one can do custom two-way filter for model, updating on the fly in Vue.js.
The following code example from docs works on input blur. But I need it work on keypress.
Vue.filter('currencyDisplay', {
read: function(val) {
return '$'+val.toFixed(2)
},
write: function(val, oldVal) {
var number = +val.replace(/[^\d.]/g, '')
return isNaN(number) ? 0 : parseFloat(number.toFixed(2))
}
})
Many thanks in advance for any help!
You can apply a filter to a Vue data property by creating a computed property with a get and set method that fire the read and write methods of the filter, respectively:
data() {
return {
foo: 0,
}
},
computed: {
filteredFoo: {
get() {
return Vue.filter('currencyDisplay').read(this.foo);
},
set(value) {
this.foo = Vue.filter('currencyDisplay').write(value);
}
}
}
Here's a working fiddle.

Vows: Testing Asynchronous Interleaving

Is there a methodology to test (potential) interleaving of asynchronous functions with vows?
For example:
// Topic portion
var user = new User('jacob')
user.set('email,'foo#bar.com')
user.save() // a
user.set('email',derp#cherp.com')
user.save() // b
user.refresh(this.callback) // Reload from database
// Callback
assert.equals(user.email,'derp#cherp.com')
There is could be a race condition between the two saves. When writing my tests I want to ensure that my API is ensuring that b finishes last (and that we have the correct final value for the email). With the way that's it written, the test will pass coincidentally some of the time.
Heres the example from the vows docs:
The nested contexts act as nested callbacks and pass the return arguments to the next context.
Docs: http://vowsjs.org/
{ topic: function () {
fs.stat('~/FILE', this.callback);
},
'after a successful `fs.stat`': {
topic: function (stat) {
fs.open('~/FILE', "r", stat.mode, this.callback);
},
'after a successful `fs.open`': {
topic: function (fd, stat) {
fs.read(fd, stat.size, 0, "utf8", this.callback);
},
'we can `fs.read` to get the file contents': function (data) {
assert.isString (data);
}
}
}
}