Three promises with HTTP - angularjs

I had to do three HTTP Post requests in my code. The first two work, I debug the code and they return the correct value, but the last one returns undefined.
I made these three requisitions due to one depending on the response of the other.
login button:
goToMenu() {
this.dados_login = [];
this.dados_login.push({
"CPF": this.cpfLogin,
"Senha": this.senhaLogin
})
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
let options = new RequestOptions({ headers: headers });
return new Promise((resolve, reject) => {
this.http.post(this.url, JSON.stringify(this.dados_login["0"]), options)
.toPromise()
.then((response) => {
var json_token = (response as any)._body;
var parsed = JSON.parse(json_token);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.token = arr[0];
this.carregaEmpresas();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
});
function that carries companies, the error occurs here because it is not returned nothing to it
carregaEmpresas(newpage: boolean = false) {
console.log(this.cpfLogin);
this.abreCarregando();
return new Promise((resolve, reject) => {
this.EmpresaProvider.getEmpresas(this.token, this.cpfLogin)
.then((response) => {
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
this.lista_empresas = arr_emp;
this.objEmp = [];
for (let i = 0; i < this.lista_empresas.length; i++) {
this.obj = {
label:
this.lista_empresas[i].Valor,
type: 'radio',
value: this.lista_empresas[i].Chave
}
this.objEmp.push(this.obj);
}
this.fechaCarregando();
this.selectEmpresa();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
});
provider role:
return new Promise((resolve, reject) => {
this.http.post(this.baseApiPath, JSON.stringify(this.cpf_usuario["0"]), options)
.toPromise()
.then((response) => {
var empresa = (response as any)._body;
var parsed = JSON.parse(empresa);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.empresa_cod = arr[0].Chave.split("/", 1);
var urlFilial = this.apiFilial + this.empresa_cod["0"];
return this.http.get(urlFilial, options);
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
return arr[0];
});
});
GetEmpresas Code:
getEmpresas(token: string, Cpf: string) {
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
headers.append('Authorization', 'bearer ' + token);
let options = new RequestOptions({ headers: headers });
this.cpf_usuario.push({ "Cpf": Cpf });
return new Promise(resolve => {
window.setTimeout(() => {
this.http.post(this.baseApiPath, JSON.stringify(this.cpf_usuario["0"]), options)
.toPromise()
.then((response) => {
var empresa = (response as any)._body;
var parsed = JSON.parse(empresa);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.empresa_cod = arr[0].Chave.split("/", 1);
var urlFilial = this.apiFilial + this.empresa_cod["0"];
return this.http.get(urlFilial, options)
.toPromise()
.then((response) => {
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
this.emp = arr_emp;
return arr_emp;
})
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
return arr[0];
});
}, 2000);
});
}

This is a draft because I'm not sure I've found the problem yet, but I need to share more code than will fit in a comment.
The first thing I would try is removing the new Promise because you aren't resolving or rejecting those promises anyway. I'd also try removing the window.setTimeout. At that point, it looks like getEmpresas will return a promise for the arr_emp that is the result of parsing the final get response. If you do that, then the then handler in carregaEmpresas will receive the arr_emp that was generated in getEmpresas, so you should just name the parameter arr_emp and not try to parse it again. The code at this point is:
class MyClass {
// Dummy declarations to suppress TypeScript errors
dados_login;
cpfLogin;
senhaLogin;
http;
url;
token;
error_login;
presentAlert;
abreCarregando;
lista_empresas;
objEmp;
obj;
fechaCarregando;
selectEmpresa;
EmpresaProvider: EmpresaProvider;
goToMenu() {
this.dados_login = [];
this.dados_login.push({
"CPF": this.cpfLogin,
"Senha": this.senhaLogin
})
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
let options = new RequestOptions({ headers: headers });
this.http.post(this.url, JSON.stringify(this.dados_login["0"]), options)
.toPromise()
.then((response) => {
var json_token = (response as any)._body;
var parsed = JSON.parse(json_token);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.token = arr[0];
this.carregaEmpresas();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
}
carregaEmpresas(newpage: boolean = false) {
console.log(this.cpfLogin);
this.abreCarregando();
this.EmpresaProvider.getEmpresas(this.token, this.cpfLogin)
.then((/*response*/ arr_emp) => {
/*
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
*/
this.lista_empresas = arr_emp;
this.objEmp = [];
for (let i = 0; i < this.lista_empresas.length; i++) {
this.obj = {
label:
this.lista_empresas[i].Valor,
type: 'radio',
value: this.lista_empresas[i].Chave
}
this.objEmp.push(this.obj);
}
this.fechaCarregando();
this.selectEmpresa();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
}
}
class EmpresaProvider {
// Dummy declarations to suppress TypeScript errors
cpf_usuario;
http;
baseApiPath;
empresa_cod;
apiFilial;
emp;
getEmpresas(token: string, Cpf: string) {
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
headers.append('Authorization', 'bearer ' + token);
let options = new RequestOptions({ headers: headers });
this.cpf_usuario.push({ "Cpf": Cpf });
return this.http.post(this.baseApiPath, JSON.stringify(this.cpf_usuario["0"]), options)
.toPromise()
.then((response) => {
var empresa = (response as any)._body;
var parsed = JSON.parse(empresa);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.empresa_cod = arr[0].Chave.split("/", 1);
var urlFilial = this.apiFilial + this.empresa_cod["0"];
return this.http.get(urlFilial, options)
.toPromise()
.then((response) => {
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
this.emp = arr_emp;
return arr_emp;
})
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
return arr[0];
});
}
}
Please try this code (integrated into your original program of course) and let me know if it works or otherwise what is the exact error and what line it occurs on.

Related

How do I display all members in the member collection, using find in mongoose

I have an application built using the MEAN Stack, I am able to display one record at a time when using this method:
in my member model I have:
module.exports.getMemberByRFID = function(rfidkey, callback){
const query = {rfidkey: rfidkey}
Member.findOne(query, callback);
}
In my routes file I have:
// Authenticate Member
router.post('/authenticatemember', (req, res, next) => {
const rfidkey = req.body.rfidkey;
Member.getMemberByRFID(rfidkey, (err, member) => {
if(err) throw err;
if(member){
const token = jwt.sign(member, config.secret, {
expiresIn: 50 //1 week
});
res.json({
success: true,
token: 'JWT2 '+token,
member: {
id: member._id,
firstname: member.firstname,
surname: member.surname,
email: member.email,
expirydate: member.expirydate
}
});
} else {
return res.json({success: false, msg: 'member not found'});
}
})
});
In my AuthService.ts file I have:
authenticateMember(member){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('http://localhost:3000/users/authenticatemember', member,{headers: headers})
.map(res => res.json());
}
And then in my angular TS file upfront I have:
onSearchSubmit(){
var inputElement = <HTMLInputElement>document.getElementById('rfidkey');
const member = {
rfidkey: inputElement.value
}
this.authService.authenticateMember(member).subscribe(data => {
if(data.success){
this.authService.storeMemberData(data.token, data.member)
console.log(data.member);
var newexpiry = new Date(data.member.expirydate);
var today = new Date();
if (today > newexpiry) {
this.flashMessage.show('member has expired', {
cssClass: 'alert-danger',
timeout: 5000});
} else {
this.flashMessage.show('member is active', {
cssClass: 'alert-success',
timeout: 5000});
}
var n = newexpiry.toString();
var inputElement = <HTMLInputElement>document.getElementById('firstname');
inputElement.value = data.member.firstname;
var inputElement = <HTMLInputElement>document.getElementById('surname');
inputElement.value = data.member.surname;
var inputElement = <HTMLInputElement>document.getElementById('email');
inputElement.value = data.member.email;
var inputElement = <HTMLInputElement>document.getElementById('expirydate');
inputElement.value = n;
// this.router.navigate(['searchmember']);
} else {
this.flashMessage.show(data.msg, {
cssClass: 'alert-danger',
timeout: 5000});
var inputElement = <HTMLInputElement>document.getElementById('firstname');
inputElement.value = "";
var inputElement = <HTMLInputElement>document.getElementById('surname');
inputElement.value = "";
var inputElement = <HTMLInputElement>document.getElementById('email');
inputElement.value = "";
var inputElement =
<HTMLInputElement>document.getElementById('expirydate');
inputElement.value = "";
this.router.navigate(['/searchmember']);
}
});
}
This gives me the following result:
Searching for a single record
Now what I want to do is have a page named Display All Members, and display all records in a datatable which can be searched and sorted.
Does anyone know how I can find ALL records with mongoose and send the list of all members to the front end Angular 2 application and place them in to the table?
thanks!

Looping in Angular with promises and http calls

my goal is to populate an array via for loop. and then send that array in HTTP POST call,
i.e: first upload all the files, then push each file details in array.
// For multiple files
for (let i = 0; i < projectRefFilesForUploading.length; i++) {
this.postSingleFile([] = projectRefFilesForUploading[i].file, projectDir).then(uploadedFiles => {
let filePath = uploadedFiles['projectRefFiles'][0].fd;
filePath = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.lastIndexOf("."));
let filename = uploadedFiles['projectRefFiles'][0].filename;
let size = uploadedFiles['projectRefFiles'][0].size;
let type = uploadedFiles['projectRefFiles'][0].type;
let status = uploadedFiles['projectRefFiles'][0].status; // finished
let fileNote = projectRefFilesForUploading[i].fileNote;
projectRefFilesDataArray.push({fileName: filename, filePath: filePath, size: size, type: type, fileNote: fileNote});
});
}
i.e: now post the array in http post call.
let body = {
projectId: projectId,
projectRefFiles: projectRefFilesDataArray
}
let headers = new Headers();
let options: RequestOptionsArgs = { headers: headers, withCredentials: true }
return new Promise((resolve, reject) => {
this.http.post( this.apiEndpoint + "/add/all", body, options).toPromise()
.then(response => {
let jsonData = response.json();
if (jsonData.apiStatus == 1) {
resolve(jsonData);
}
else reject(jsonData.message);
})
.catch(reason => reject(reason.statusText));
});
the problem is due to async function calls, http call post its data in parallel to loop execution. so it sends an empty array in http call. if I put the call method inside the loop then it works. but it created too much http call along with looping.
please help me how to detect, loop finishes it execution then after http call
try this :
let promise = new Promise((resolve, reject) => {
let count = 0;
for (let i = 0; i < projectRefFilesForUploading.length; i++) {
this.postSingleFile([] = projectRefFilesForUploading[i].file, projectDir).then(uploadedFiles => {
count++;
let filePath = uploadedFiles['projectRefFiles'][0].fd;
filePath = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.lastIndexOf("."));
let filename = uploadedFiles['projectRefFiles'][0].filename;
let size = uploadedFiles['projectRefFiles'][0].size;
let type = uploadedFiles['projectRefFiles'][0].type;
let status = uploadedFiles['projectRefFiles'][0].status; // finished
let fileNote = projectRefFilesForUploading[i].fileNote;
projectRefFilesDataArray.push({fileName: filename, filePath: filePath, size: size, type: type, fileNote: fileNote});
if(count === projectRefFilesForUploading.length){
resolve(projectRefFilesForUploading);
}
});
}
});
promise.then(function(projectRefFilesDataArray){
let body = {
projectId: projectId,
projectRefFiles: projectRefFilesDataArray
}
let headers = new Headers();
let options: RequestOptionsArgs = { headers: headers, withCredentials: true }
return new Promise((resolve, reject) => {
this.http.post( this.apiEndpoint + "/add/all", body, options).toPromise()
.then(response => {
let jsonData = response.json();
if (jsonData.apiStatus == 1) {
resolve(jsonData);
}
else reject(jsonData.message);
})
.catch(reason => reject(reason.statusText));
});
});

nightmare how to looply select the selector

var Nightmare = require('nightmare');
var nightmare = Nightmare({ show: true });
var fs = require('fs');
var result;
nightmare
.goto('http://football-system.jp/fss/pub_penaltylist.php?lid=eBVesRz5C54=')
.wait('select[name="selectTeam"]')
.evaluate(function () {
var options = document.querySelectorAll('option'),i;
var values =[]
for (i = 1; i < options.length; ++i) {
values.push(options[i].value)
}
return values;
})
.then(function (values) {
console.log(values)
values.reduce(function(accumulator, value) {
return accumulator.then(function(results) {
return nightmare.goto("http://football-system.jp/fss/pub_penaltylist.php?lid=eBVesRz5C54=")
.wait('select[name="selectTeam"]')
.select('select[name="selectTeam"]', value)
.wait('button[onClick="selectData();"]')
.click('button[onClick="selectData();"]')
.wait('table[class="tableOutputDate"]')
.evaluate(function () {
return document.querySelector('table[class="tableOutputDate"]').textContent;
})
.then(function(result){
console.log(result)
results.push(result);
return results;
});
});
}, Promise.resolve([])).then(function(results){
console.log(results)
});
})
.catch(function (error) {
console.error('Search failed:', error);
});
That is my code .I want to looping select all the selector in that page and get the all html data.I asked a question in here that how to loop in nightmare,but that result cant solve this problem.please help me. Thank you.
I solve my question.the problem is happened in the deal time,not in the loop logic.I add some more wait(time).I think wait(time)is better than the wait(selector).so is over. thank u attention.
var run = function * () {
//var values = ['http://www.yahoo.com', 'http://example.com', 'http://w3c.org'];
var titles = [];
for (var i = 0; i < values.length; i++) {
var title = yield nightmare.goto('.............')
//.wait('select[name="selectTeam"]')
.wait(2000)
.select('select[name="selectTeam"]', values[i])
.wait(2000)
.click('button[onClick="selectData();"]')
//.wait('table[class="tableOutputDate"]')
.wait(2000)
.evaluate(function () {
//return document.querySelector('table[class="tableOutputDate"]').textContent;
var divs = document.querySelectorAll('table[class="tableOutputDate"]'),i;
var tables = []
for (i = 0; i < divs.length; ++i) {
tables.push(divs[i].textContent)
//result += divs[i].href.toString()+"\n";
}
return tables;
})
titles.push(title);
}
return titles;
}
vo(run)(function(err, titles) {
console.dir(titles);
});

Does an angular.forEach create it's own scope?

My code has this HTML snippet:
<div ng-repeat="wf in wos.word.wordForms">
{{ wf }}
<textarea ng-change="wf.statusId = 2"
ng-model="wf.definition">
</textarea>
...
In a service I have this:
wordFormCheckAndUpdate = (): ng.IPromise<any> => {
var self = this;
var promises = [];
angular.forEach(self.word.wordForms, function (wf, key) {
if (wf.statusId == Status.Dirty) {
if (wf.createdDate) {
var updatePromise = self.wordFormUpdateSubmit(wf);
promises.push(updatePromise);
} else {
var addPromise = self.wordFormAddSubmit(wf);
promises.push(addPromise);
}
}
});
return self.$q.all(promises);
};
wordFormAddSubmit and wordFormUpdateSubmit modify the data in wf:
wf = angular.copy(response.data);
wf.statusId = 3;
wf.abc = "test"
When one of these functions is called it does not seem to change what is displayed above the textarea and the statusId still shows as 2 and "test" does not appear. Does anyone have any ideas what might be happening?
Update. Here are the two functions that are called:
wordFormAddSubmit = (wf: IWordForm): ng.IPromise<any> => {
var self = this;
return self.$http({
url: self.ac.dataServer + "/api/WordForm/Post",
method: "POST",
data: wf
})
.then(
(response: ng.IHttpPromiseCallbackArg<IWordForm>): any => {
wf = angular.copy(response.data);
self.$timeout(function () {
wf.statusId = 3;
wf.sourceId = 999;
}, 3);
},
(error: ng.IHttpPromiseCallbackArg<any>): any => {
self.ers.error(error);
return self.$q.reject(error);
});
}
wordFormUpdateSubmit = (wf: IWordForm): ng.IPromise<any> => {
var self = this;
return self.$http({
url: self.ac.dataServer + "/api/WordForm/Put",
method: "PUT",
data: wf
})
.then(
(response: ng.IHttpPromiseCallbackArg<IWordForm>): any => {
wf = angular.copy(response.data);
//$timeout(function () {
wf.statusId = 3;
//}, 1);
var a = wf;
var b = wf;
},
(error: ng.IHttpPromiseCallbackArg<any>): any => {
self.ers.error(error);
return self.$q.reject(error);
});
}

How to make this asynchronous call, synchronous

I have an associative array date as key, the value in this case is an array of objects. Now in this object
while (tempDate < endDate) {
$scope.dates.push(tempDate.format("DD-MM-YYYY"));
var dailyTrips = response.data[tempDate.format("DD-MM-YYYY")];
for (var i = 0; i < dailyTrips.length; i++) {
// console.log(moment(dailyTrips[i].trip.startTime).format("hh:mm a"));
// console.log(moment(dailyTrips[i].trip.endTime).format("hh:mm a"));
geocode(dailyTrips, i);
}
tempDate.add(1, 'days');
}
$scope.data = response.data;
var geocode = function(dailyTrips, i) {
(function() {
var latlng = {
lat: dailyTrips[i].trip.source.latitude,
lng: dailyTrips[i].trip.source.longitude
};
console.log(latlng);
var geocoder = new google.maps.Geocoder;
geocoder.geocode({
'location': latlng
}, function(result, status) {
if (result[1]) {
console.log(result[1].address_components[0].long_name+" "+result[1].address_components[2].long_name);
}
});
}(i));
};
Now This code is working but running at completely different times as it's a callback. I wanted to have this all at one time so that I can use it in ng-repeat and show everything nicely. How do I do that?
Expected output
Trip StartTime Trip from
Trip EndLine Trip To
EDIT 1: Still not working
while (tempDate < endDate) {
$scope.dates.push(tempDate.format("DD-MM-YYYY"));
var dailyTrips = response.data[tempDate.format("DD-MM-YYYY")];
var promises = [];
for (var i = 0; i < dailyTrips.length; i++) {
promises[i] = geocode(dailyTrips, i);
}
$q.all(promises).then(function(result) {
console.log(result); //line 39
});
tempDate.add(1, 'days');
}
$scope.data = response.data;
}, function(error) {
console.log(error.data);
});
var geocode = function(dailyTrips, i) {
var q = $q.defer();
var latlng = {
lat: dailyTrips[i].trip.source.latitude,
lng: dailyTrips[i].trip.source.longitude
};
console.log(latlng);
var geocoder = new google.maps.Geocoder;
geocoder.geocode({
'location': latlng
}, function(result, status) {
console.log(status);
if (status === google.maps.GeocoderStatus.OK) {
console.log(result[1].address_components[0].long_name + " " + result[1].address_components[2].long_name);
q.resolve(result[1].address_components[0].long_name + " " + result[1].address_components[2].long_name);
} else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(function() {
geocode(dailyTrips, i);
}, 500);
} else {
q.reject();
}
});
return q.promise;
};
You cannot make an async call synchronous, except by blocking your code, which you do no NOT want to do. Instead, I suggest you convert geocode into a promise
var geocode = function(dailyTrips, i) {
return this.$q((resolve, reject) => {
....
and then wait for all the promises to complete
var promises = [];
for (var i = 0; i < dailyTrips.length; i++) {
promises[i] = geocode(dailyTrips, i);
}
$q.all(promises).then( function(results) {...} );

Resources