Wrapping a ajax call - javascript

I have a code, that will make inside the select function an ajax request.
oSelect
.select(function (oEvent) {
return oEvent.getSource();
})
.select(function (oControl) {
let oItem = oControl.getSelectedItem();
let aKeys = oItem.getKey().split("/");
return {plant: aKeys[0], wc: aKeys[1]};
})
.select(function (oSelectedItem) {
let oModel = self.getModel("weightProtocolService");
let oPlantFilter = new Filter("Plant", sap.ui.model.FilterOperator.EQ, oSelectedItem.plant);
let oWcFilter = new Filter("WorkCenter", sap.ui.model.FilterOperator.EQ, oSelectedItem.wc);
oModel.read("/CostCenterCalendarSet", {
success: function (oData, oResponse) {
return Rx.Observable.from(oResponse.data.results);
},
error: function (oError) {
return Rx.Observable.throw(oError);
},
filters: [oPlantFilter, oWcFilter]
});
})
.subscribe(function (oKey) {
console.log(oKey);
},
function (err) {
jQuery.sap.log.fatal(err);
});
My problem here is, that it will subscribe first before the ajax response appears.
How can I solve the problem?

Assuming RxJS 5, replace the last select with a mergeMap and return a new observable:
.mergeMap(function (oSelectedItem) {
let oModel = self.getModel("weightProtocolService");
let oPlantFilter = new Filter("Plant", sap.ui.model.FilterOperator.EQ, oSelectedItem.plant);
let oWcFilter = new Filter("WorkCenter", sap.ui.model.FilterOperator.EQ, oSelectedItem.wc);
return new Observable(observer => {
oModel.read("/CostCenterCalendarSet", {
success: function (oData, oResponse) {
observer.next(oResponse.data.results);
},
error: function (oError) {
observer.error(oError);
},
filters: [oPlantFilter, oWcFilter]
});
});
})

If oModel.read returns a promise, then you can simply do the following:
....
return Observable.fromPromise(oModel.read("/CostCenterCalendarSet", {
filters: [oPlantFilter, oWcFilter]
})
);
If oModel.read does not return a promise, then you would need a custom observable:
....
return Observable.create(function(observer) {
oModel.read("/CostCenterCalendarSet", {
success: function (oData, oResponse) {
return observer.onNext(oResponse.data.results); // or just .next(..) in case you are using rxjs5+
},
error: function (oError) {
return observer.onError(oError); // or just .error(..) in case you are using rxjs5+
},
filters: [oPlantFilter, oWcFilter]
});
});

Related

How to return variable value outside api function call using jquery or javascript

module.exports = function (ctx, application) {
var API;
var usermandData = [];
var clientmandData = [];
var taskmandData = []
API = {
GetMandatoryFieldsforUser: function () {
return MandatoryFields.User;
},
GetMandatoryFieldsforClient: function () {
return MandatoryFields.Client;
},
GetMandatoryFieldsforTask: function () {
return MandatoryFields.Task;
}
};
var UserFields = $.get("api/mapping/mandatoryfield?type=USER", function (d) {
this.mandatoryuserdata = JSON.parse(d.Data);
this.mandatoryuserdata.forEach(function (data) {
usermandData.push(data.DisplayName); // returns ["First Name", "Last Name", "Location", "Email"]
});
})
var ClientFields = $.get("api/mapping/mandatoryfield?type=CLIENT", function (d) {
this.mandatoryClientdata = JSON.parse(d.Data);
this.mandatoryClientdata.forEach(function (data) {
clientmandData.push(data.DisplayName); // returns ["Client Type", "Last Name / Entity Name", "Originating Location", "Responsible Person"],
});
})
var TaskFields = $.get("api/mapping/mandatoryfield?type=TASK", function (d) {
this.mandatoryTaskdata = JSON.parse(d.Data);
this.mandatoryTaskdata.forEach(function (data) {
taskmandData.push(data.DisplayName); //returns ["Client Name", "Period End Date", "Task Type", "Responsible Person"]
});
})
MandatoryFields = {
User: usermandData,
Client: clientmandData,
Task: taskmandData
}
Reqres.setHandler('Dataexportwizard:getMandatoryfields', function (type) {
// console.log(mandData)
switch (type) {
case "USER": return API.GetMandatoryFieldsforUser();
case "CLIENT": return API.GetMandatoryFieldsforClient();
case "TASK": return API.GetMandatoryFieldsforTask();
}
});
My issue here is since it is a async function MandatoryFields.User, MandatoryFields.Client and MandatoryFields.Task returns null value i need to push value of usermandData, clientmandData, taskmandData into MandatoryFields.User , MandatoryFields.Client , MandatoryFields.Task field How to achieve it using jquery or javascript.
since MandatoryFields object executes before jQuery get method I can only use values inside function call but i need to use it inside MandatoryFields object how can i achieve it using jquery
One of the best solution to handle these type of async tasks to use "Promises" (JS feature added by ES6). Try this code may be this will help : -
module.exports = function (ctx, application) {
var API;
var usermandData = [];
var clientmandData = [];
var taskmandData = []
API = {
GetStepContainerData: function () {
return StepContainerData;
},
GetStepData: function () {
return stepData;
},
GetMandatoryFieldsforUser: function () {
return MandatoryFields.User;
},
GetMandatoryFieldsforClient: function () {
return MandatoryFields.Client;
},
GetMandatoryFieldsforTask: function () {
return MandatoryFields.Task;
}
};
Promise.all([
new Promise(function(resolve,reject){
$.get("api/mapping/mandatoryfield?type=USER", function (d) {
this.mandatoryuserdata = JSON.parse(d.Data);
this.mandatoryuserdata.forEach(function (data) {
usermandData.push(data.DisplayName); // returns ["First Name", "Last Name", "Location", "Email"]
});
resolve();
});
}),
new Promise(function(resolve,reject){
$.get("api/mapping/mandatoryfield?type=CLIENT", function (d) {
this.mandatoryClientdata = JSON.parse(d.Data);
this.mandatoryClientdata.forEach(function (data) {
clientmandData.push(data.DisplayName); // returns ["Client Type", "Last Name / Entity Name", "Originating Location", "Responsible Person"],
});
resolve();
})
}),
new Promise(function(resolve,reject){
$.get("api/mapping/mandatoryfield?type=TASK", function (d) {
this.mandatoryTaskdata = JSON.parse(d.Data);
this.mandatoryTaskdata.forEach(function (data) {
taskmandData.push(data.DisplayName); //returns ["Client Name", "Period End Date", "Task Type", "Responsible Person"]
});
resolve();
});
})
]
).then(function(result){
// After resolving all the promises this method will execute
MandatoryFields = {
User: usermandData,
Client: clientmandData,
Task: taskmandData
}
});
Reqres.setHandler('Dataexportwizard:getMandatoryfields', function (type) {
// console.log(mandData)
switch (type) {
case "USER": return API.GetMandatoryFieldsforUser();
case "CLIENT": return API.GetMandatoryFieldsforClient();
case "TASK": return API.GetMandatoryFieldsforTask();
}
});

Error in Returning Promise ,Getting Error as .then is not a function in Angular JS

I am getting the error as modifyProduct.then is not a function, I have read through some article and it says because I have not returned any promises, How I can achieve this, Can someone help me
Here I am calling modifyProduct inside executionFromCompany function and then I am using executionFromCompany inside the controller
var app = angular.module('myApp', ["chart.js"]);
app.factory('ProductsService', function($http) {
function getProduct() {
return $http.get('finalmsodetails.json').then(function(response) {
//console.log(response.data);
return response.data;
});
}
function modifyProduct() {
return getProduct().then(function(rawData) {
newtest = rawData;
//console.log('test', newtest.length);
var lightData = rawData.map(function(item) {
// use Object.assign to prevent mutating original object
var newItem = Object.assign({}, item);
var lightExecutions = item.executions.map(function(d) {
var ld = {
id: d.id,
orderId: d.orderId,
executionStatus: d.executionStatus,
executedOn: d.executedOn,
executedBy: d.executedBy,
executedByDisplay: d.executedByDisplay,
};
return ld;
});
newItem.executions = lightExecutions;
return newItem;
});
return lightData;
});
}
function executionFromCompany() {
return modifyProduct.then(function(lightData) {
executionByCompany = $filter('filter')(lightData.executions, function(inputs) {
if ((inputs.executedBy == 'a')) return inputs;
});
console.log(executionByCompany);
return executionByCompany;
});
}
return {
getProduct: getProduct,
modifyProduct: modifyProduct,
executionFromCompany: executionFromCompany
};
});
app.controller('MainCtrl', function($scope, ProductsService) {
ProductsService.executionFromCompany().then(function(value) {
console.log(value);
}, function(err) {
// Here will be if there was an error
})
});
modifyProduct is a function, not an object
change this
modifyProduct.then
to this
modifyProduct().then

Cannot access data from component method

I tried components methods in vue js. My code like this.
const Thread = Vue.component('threadpage', function(resolve) {
$.get('templates/thread.html').done(function(template) {
resolve({
template: template,
data: function() {
return {
data: {
title: "Data Table",
count: this.GetData
}
};
},
methods: {
GetData: function() {
var data = {
username : "newshubid",
data : {
page : 0,
length : 10,
schedule : "desc"
}
};
var args = {"data" : JSON.stringify(data)};
var params = $.param(args);
var url = "http://example-url";
var result;
DoXhr(url, params, function(response){
result = JSON.parse(response).data;
console.log("load 1", result);
});
setTimeout(function () {
console.log("load 2", result);
return result;
}, 1000);
}
},
created: function(){
this.GetData();
}
});
});
});
But, when I trying to use {{ data.count }} in template. Not showing result what i want. Even I tried return result in GetData.
Whats my problem ? And how to access data from methods ? Please help me, i'm a beginner. Thanks
See the edited code and comments I added below.
You tried to return the result by using return in the function from setTimeout, which won't help you return value from GetData.
Instead, You can just set the value in the callback function of your ajax request.
const Thread = Vue.component('threadpage', function(resolve) {
$.get('templates/thread.html').done(function(template) {
resolve({
template: template,
data: function() {
return {
data: {
title: "Data Table",
// NOTE just set an init value to count, it will be refreshed when the function in "created" invoked.
count: /* this.GetData */ {}
}
};
},
methods: {
GetData: function() {
var data = {
username : "newshubid",
data : {
page : 0,
length : 10,
schedule : "desc"
}
};
var args = {"data" : JSON.stringify(data)};
var params = $.param(args);
var url = "http://example-url";
var result;
var vm = this;
DoXhr(url, params, function(response){
result = JSON.parse(response).data;
// NOTE set data.count to responsed result in callback function directly.
vm.data.count = result;
});
// NOTE I think you don't need code below anymore.
// setTimeout(function () {
// console.log("load 2", result);
// return result;
// }, 1000);
}
},
created: function(){
this.GetData();
}
});
});
});

How to make module pattern each function a promise?

I use Angular 1.5 and I made a factory function which is return a literal object like this:
return {
item: null,
get: function() {
return item;
},
create: function() {
if (this.get()){
this.remove();
}
this.item = {};
},
remove: function() {
var item = this.get();
if (item) {
this.item = null;
}
},
add: function() {
if (!this.get()) {
this.create();
}
this.item.newprop = 'value';
}
}
please do not ask me to change to function declaration. I want a object with his own actions(functions) and properties that is working on.
This pattern (like get inside create so on..) I didn't copied from anywhere. so I'm wonder if has a name? It is best way to deal with function-black boxes?
What is the best way to put Promise inside? so every function should return a promise
every then function I need to use bind???
todo like this:
create: function () {
this.get()
.then(remove)
.then(function () {
this.item = {}; // BUT this === undefined!!
});
}
You have to use bind in every then callback function:
var myModule = {
item: null,
get: function() {
return Promise.resolve(this.item);
},
create: function() {
return this.remove().then(function() {
this.item = {};
}.bind(this));
},
remove: function() {
return this.get().then(function(item) {
if (item) {
this.item = null;
}
}.bind(this));
},
add: function() {
return this.get().then(function(item) {
return item || this.create();
}.bind(this)).then(function() {
this.item.newprop = 'value';
}.bind(this));
}
}
// Let see it working:
myModule.create().then(function() {
return myModule.get();
}).then(function(item) {
console.log("After create: ", item);
return myModule.remove();
}).then(function() {
return myModule.get();
}).then(function(item) {
console.log("After remove: ", item);
return myModule.add();
}).then(function() {
return myModule.get();
}).then(function(item) {
console.log("After add: ", item);
});

how nicely solve selenium promise? protractor

I wrote the following code (page object pattern). Works correctly.
However, I don't like this, because I can't remove "then" from "pressHelpLink". Instead add the code in getElementByLink.
I would like to see ElementFinder Promise (instead of ManagedPromise) as result of getElementByLink("Help")
How nicely solve selenium promise?
var self = Page.create({
url: {value: ''},
// function:
getElementByLink: {
value: function (link) {
return element.all(by.repeater('items')).then(function (el) {
var my_array = el.map(function (el) {
return el.element(self.by.xpath('a'));
});
var element_array_finder = protractor.ElementArrayFinder.fromArray(my_array);
var element = element_array_finder.filter(function (el) {
return el.getText().then(function (text) {
return text === link;
})
});
return element;
}).then(function (element) {
world.expect(element.length).equal(1);
return element[0];
});
}
},
// elements:
HelpLink: {
get: function () {
return self.getElementByLink('Help');
}
},
// method:
pressHelpLink: {
value: function () {
return self.HelpLink.then(function (el) {
return el.click()
});
}
},
});
Why not use cssContainingText? Maybe something like...
// elements:
HelpLink: {
get: function () {
return element(by.cssContainingText('a', 'Help');
}
},
// method:
pressHelpLink: {
value: function () {
return self.HelpLink.click()
}
},

Categories