问题
EDIT
I consoled if the script is entering the addHousehold() if condition at:
addHouseholdPromise.then((res) => {
console.log("Promise HH: "+res)
if (res != "add_hh_fail") {
console.log("success: "+res)
return res;
}
else {
console.log("fail: "+res)
// Add to addHousehold array log
this.addHHArray(row)
}
})
And it returned the value, but when I intercept it at the main function, it becomes undefined
.
END EDIT
Original Post
I have a main function, which loop over an array fromArray
, and it takes each row of it and do the following:
- add the hoousehold to database using
this.api.postData(array)
; - Enroll into a program
program_from
After enrollment, we go into another loop to loop over another array
toArray
which will contain members, and add members who are related the rowfromArray
and having the following condition:if (row_hh['hh_new_id'] == row_mbr['hh_new_id'])
After adding the related members, we enroll them into another program
program_to
;At the end, we take each
hh_id
and each relatedmbr_id
and connect them throughaddRelation()
.
**I. Main Method: **
uploadDataV3(fromArray, toArray) {
let workBook = null;
this.lengthFromArray = fromArray.length;
this.lengthToArray = toArray.length;
this.fromArrayUnsuccess = [];
this.toArrayUnsuccess = [];
this.arrayOfUnsuccessRelationInsert = [];
this.fromArrayUnsuccessEnroll = [];
this.toArrayUnsuccessEnroll = [];
this.globalArray = [];
let registered_hh_id = '';
let registered_mbr_id = '';
this.relationIDsArray = [];
let myDate = new Date();
let enrollDate = this.datePipe.transform(myDate, 'yyyy-MM-dd');
let hh_id: any = '';
let mbr_id: any = '';
fromArray.forEach((row_hh, hh_idx) => {
// Add household to household entity (table)
hh_id = this.addHousehold(row_hh);
console.log('HH ID: '+hh_id)
// Enroll Household to program_from
let hh_id_enroll_response = this.enrollHousehold(hh_id, row_hh);
console.log('Enroll Response: '+hh_id_enroll_response)
if (hh_id_enroll_response == true) {
toArray.forEach((row_mbr, mbr_idx) => {
if (row_hh['hh_new_id'] == row_mbr['hh_new_id']) {
mbr_id = this.addMember(row_mbr);
console.log('Member ID: '+mbr_id)
// Enroll new member id to program_to
let mbr_id_enroll_response = this.enrollMember(mbr_id, row_mbr);
if (mbr_id_enroll_response == true) {
// Add relationship between each household and its related members
this.addRelation(hh_id, mbr_id);
}
}
})
}
});
}
The main problem now is at this line:
hh_id = this.addHousehold(row_hh);
console.log('HH ID: '+hh_id)
the returned value is undefined
as it's shown in the image down below:
At the addHousehold()
method, it's showing the generated id registered_hh_id
:
console.log("check hh_id", this.registered_hh_id);
Even at the promise of the function:
addHouseholdPromise.then((res) => {
console.log("Promise HH: "+res)
if (res != "add_hh_fail") {
return res;
}
else {
// Add to addHousehold array log
this.addHHArray(row)
}
})
This line is showing the returned ID:
console.log("Promise HH: "+res)
So the problem is that inside the add Household method is getting the ID from the server but it's returning it as undefined
.
Here are the detailed methods used in the main function as well
II. For the Add household:
addHousehold(row) {
console.log(row)
let addHouseholdPromise = new Promise((resolve, reject) => {
let attributes = [
{ attribute: "lhMhyp9F1kg", value: row["HH_last_name"] != "" ? row["HH_last_name"] : "" },
{ attribute: "v4nxGLRD3n8", value: row["HH_status"] != "" ? row["HH_status"] : "" },
{ attribute: "rgBt6xSDLPp", value: row["reason_of_inactivation"] != "" ? row["reason_of_inactivation"] : "" },
{ attribute: "w3VYFaC2tnF", value: row["old_lmms_id"] != "" ? row["old_lmms_id"].toString() : "" },
{ attribute: "TN0ZUAIq3jr", value: row["hh_new_id"] != "" ? row["hh_new_id"].toString() : "" },
{ attribute: "g8EjIWItCxm", value: row["registration_date"] != "" ? row["registration_date"] : "" },
]
let data = {
trackedEntityType: this.formGroup.controls.entity_from.value,
orgUnit: this.formGroup.controls.organization.value,
attributes: attributes
}
this.registered_hh_id = '';
this.api.postData(data).subscribe(
(response_hh) => {
if (response_hh['httpStatus'] == "OK" && response_hh['httpStatusCode'] == 200 && response_hh['message'] == "Import was successful.") {
this.registered_hh_id = response_hh['response']['importSummaries'][0]['reference'];
console.log("check hh_id", this.registered_hh_id);
resolve(this.registered_hh_id)
}
else {
resolve("add_hh_fail");
}
},
(error_hh) => {
reject("add_hh_fail");
console.log(error_hh)
}
);
})
addHouseholdPromise.then((res) => {
console.log("Promise HH: "+res)
if (res != "add_hh_fail") {
return res;
}
else {
// Add to addHousehold array log
this.addHHArray(row)
}
})
}
**III. Enroll household: **
enrollHousehold(hh_id, row_hh) {
let myDate = new Date();
let result:boolean;
let enrollDate = this.datePipe.transform(myDate, 'yyyy-MM-dd');
let enrollHouseholdPromise = new Promise((resolve, reject) => {
this.api.makeEnrollment(hh_id,
this.formGroup.controls.program_from.value, "ACTIVE",
this.formGroup.controls.organization.value,
enrollDate, enrollDate)
.subscribe(
(response_hh_enroll) => {
if (response_hh_enroll['httpStatus'] == "OK" && response_hh_enroll['httpStatusCode'] == 200 && response_hh_enroll['message'] == "Import was successful.") {
resolve("hh_enroll_success");
}
else {
reject("hh_enroll_fail");
// this.addHHArrayEnroll(row_hh)
}
},
(error_hh_enroll) => {
console.log(error_hh_enroll);
// this.addHHArrayEnroll(row_hh)
reject("hh_enroll_fail")
}
)
})
enrollHouseholdPromise.then((res) => {
if (res == "hh_enroll_success") {
result = true;
}
else {
this.addHHArrayEnroll(row_hh);
result = false;
// Add to logs
}
})
return result;
}
**IV. After the enroll, we'll add the member: **
addMember(row_mbr) {
let mbr_attributes = [
{ attribute: "TN0ZUAIq3jr", value: row_mbr["hh_new_id"].toString() },
{ attribute: "YvQdThw2NdW", value: row_mbr["mbr_new_id"].toString() },
{ attribute: "jQrM04xaPxb", value: row_mbr["first_name"] != "" ? row_mbr["first_name"] : "" },
{ attribute: "CybsW0GygpD", value: row_mbr["last_name"] != "" ? row_mbr["last_name"] : "" },
{ attribute: "RwRUmhHpSKS", value: row_mbr["father_name"] != "" ? row_mbr["father_name"] : "" },
{ attribute: "wXbpKsIbSRH", value: row_mbr["mother_full_name"] != "" ? row_mbr["mother_full_name"] : "" },
{ attribute: "CtJzimjQTYJ", value: row_mbr["gender"] != "" ? row_mbr["gender"] : "" },
{ attribute: "CtWcqFJCFXV", value: row_mbr["relation_to_HH"] != "" ? row_mbr["relation_to_HH"] : "" },
{ attribute: "qaOqvRz6TNb", value: row_mbr["DOB"] != "" ? this.datePipe.transform(row_mbr["DOB"], "yyyy-MM-dd") : "" },
{ attribute: "lTjjW15jAmv", value: row_mbr["phone_number"] != "" ? row_mbr["phone_number"].toString() : "" },
{ attribute: "CGjfVDBVlqV", value: row_mbr["nationality"] != "" ? row_mbr["nationality"] : "" },
{ attribute: "yo33iKOsHfN", value: row_mbr["other_nationality"] != "" ? row_mbr["other_nationality"] : "" },
{ attribute: "lk1jkG6UK6a", value: row_mbr["unhcr_exists"] != "" ? row_mbr["unhcr_exists"] : "" },
{ attribute: "XskAQYfw4sx", value: row_mbr["unhcr_id"] != "" ? row_mbr["unhcr_id"] : "" },
{ attribute: "Olq1PTOXLSb", value: row_mbr["other_gov_id"] != "" ? row_mbr["other_gov_id"] : "" },
{ attribute: "E63TvSeUUnl", value: row_mbr["other_gov_id_number"] != "" ? row_mbr["other_gov_id_number"] : "" },
{ attribute: "v4nxGLRD3n8", value: row_mbr["mbr_status"] != "" ? row_mbr["mbr_status"] : "" },
{ attribute: "RbXBwAN4Fbq", value: row_mbr["reason_inactive"] != "" ? row_mbr["reason_inactive"] : "" },
{ attribute: "EN5E32lCYNa", value: row_mbr["coordinates"] },
{ attribute: "cWXekTraGOx", value: row_mbr["comments"] != "" ? row_mbr["comments"].toString() : "" }
]
let mbr_data = {
trackedEntityType: this.formGroup.controls.entity_to.value,
orgUnit: this.formGroup.controls.organization.value,
attributes: mbr_attributes
}
let addMemberPromise = new Promise((resolve, reject) => {
this.api.postData(mbr_data).subscribe(
(response_mbr) => {
if (response_mbr['httpStatus'] == "OK" && response_mbr['httpStatusCode'] == 200 && response_mbr['message'] == "Import was successful.") {
this.registered_mbr_id = response_mbr['response']['importSummaries'][0]['reference'];
resolve(this.registered_mbr_id);
}
else {
resolve("add_mbr_fail");
}
},
(error_mbr) => {
reject("add_mbr_fail");
console.log(error_mbr)
}
);
});
addMemberPromise.then((res) => {
if (res != "add_mbr_fail") {
return res;
}
else {
// Add to logs array
this.addMbrArray(row_mbr);
}
})
}
**V. After adding the member, we enroll it into a program: **
enrollMember(mbr_id, row_mbr) {
let myDate = new Date();
let result:boolean;
let enrollDate = this.datePipe.transform(myDate, 'yyyy-MM-dd');
let enrollMemberEnroll = new Promise((resolve, reject) => {
this.api.makeEnrollment(mbr_id, this.formGroup.controls.program_to.value,
"ACTIVE", this.formGroup.controls.organization.value,
enrollDate, enrollDate)
.subscribe(
(response_mbr_enroll) => {
if (response_mbr_enroll['httpStatus'] == "OK" && response_mbr_enroll['httpStatusCode'] == 200 && response_mbr_enroll['message'] == "Import was successful.") {
resolve("mbr_enroll_success");
}
else {
resolve("mbr_enroll_fail")
}
},
(error_mbr_enroll) => {
reject("mbr_enroll_fail");
console.log(error_mbr_enroll)
}
);
});
enrollMemberEnroll.then((res) => {
if (res == "mbr_enroll_success") {
result = true;
}
else {
// Add to enroll logs
this.addMbrArrayEnroll(row_mbr);
result = false;
}
})
return result;
}
**VI. And at the end we add a relation between the hh_id
and all its related mbr_id
: **
addRelation(hh_id, mbr_id) {
let myDate = new Date();
let enrollDate = this.datePipe.transform(myDate, 'yyyy-MM-dd');
let checkExistingRelationshipsPromise = new Promise((resolve, reject) => {
this.api.existingRelationships(hh_id, this.formGroup.controls.program_from.value).subscribe(
(relation) => {
console.log(relation, relation['relationships'].length, this.relations)
// if (relation['httpStatusCode'] == 200 && relation['httpStatus'] == 'OK') {
if (relation['relationships'].length > 0) {
this.relations = relation['relationships']
resolve('relation_exists')
}
else {
this.relations = [];
resolve('no_relations')
}
}, (error) => {
reject("rejected")
console.log("relations api: " + error)
})
});
checkExistingRelationshipsPromise.then((res) => {
if (res == "rejected") {
console.log("error occured while getting existing relations")
}
else {
console.log(hh_id, mbr_id)
}
let addRelationshipPromise = new Promise((resolve, reject) => {
let programOwners = [{
ownerOrgUnit: this.formGroup.controls.organization.value,
program: this.formGroup.controls.program_from.value,
trackedEntityInstance: hh_id
}];
let relationships: any[] = []
if (res == "relation_exists") {
this.relations.forEach((val, idx) => {
relationships.push(val)
})
// relationships.push(this.relations)
console.log(relationships)
}
relationships.push(
{
lastUpdated: this.datePipe.transform(myDate, 'yyyy-MM-ddTHH:mm:ss'),
created: this.datePipe.transform(myDate, 'yyyy-MM-ddTHH:mm:ss'),
relationshipName: "LBN_HH_MBR_Relationship",
bidirectional: false,
relationshipType: this.formGroup.controls.relation_id.value,
// relationship: "wMECqtsc47R",
from: {
trackedEntityInstance: {
trackedEntityInstance: hh_id,
programOwners: []
}
},
to: {
trackedEntityInstance: {
trackedEntityInstance: mbr_id,
programOwners: []
}
},
// relationshipType: this.formGroup.controls.relation_id.value
}
);
let data = {
created: this.datePipe.transform(myDate, 'yyyy-MM-ddTHH:mm:ss'),
orgUnit: this.formGroup.controls.organization.value,
createdAtClient: this.datePipe.transform(myDate, 'yyyy-MM-ddTHH:mm:ss'),
trackedEntityInstance: hh_id,
lastUpdated: this.datePipe.transform(myDate, 'yyyy-MM-ddTHH:mm:ss'),
trackedEntityType: this.formGroup.controls.entity_from.value,
lastUpdatedAtClient: this.datePipe.transform(myDate, 'yyyy-MM-ddTHH:mm:ss'),
inactive: false,
deleted: false,
featureType: "NONE",
programOwners: programOwners,
relationships: relationships
// attributes: attributes
}
this.relationIDsArray.push(
{
hh_id: hh_id,
mbr_id: mbr_id,
data: data
}
)
// this.addRelation(response_hh['response']['importSummaries'][0]['reference'], response_mbr['response']['importSummaries'][0]['reference'], data);
this.api.addRelation(hh_id, data).subscribe(
(response_relation) => {
if (response_relation['httpStatusCode'] == 200 && response_relation['httpStatus'] == "OK"
&& response_relation['message'] == 'Import was successful.') {
resolve("relation added");
}
else {
resolve("relation was not added");
this.addUnsuccessRelationInsert(hh_id,
mbr_id,
this.formGroup.controls.entity_from.value, this.formGroup.controls.organization.value, this.formGroup.controls.relation_id.value)
}
},
(error) => {
console.log(error);
this.addUnsuccessRelationInsert(hh_id,
mbr_id,
this.formGroup.controls.entity_from.value, this.formGroup.controls.organization.value, this.formGroup.controls.relation_id.value)
return false;
}
);
})
addRelationshipPromise.then((res) => {
if (res == "relation added") {
console.log("Relation Added")
}
else {
console.log("Error while adding the relationship")
}
})
})
}
回答1:
You are returning the value using the return keyword in then()
callback method of Promises. That won't work. The function you pass inside then()
will be executed sometime in the future when the promise is resolved. So if you want to wait will your promise resolves to get the value, use ES6 async-await
approach.
async addHousehold(row) {
console.log(row)
let addHouseholdPromise = new Promise((resolve, reject) => {
// Your logic goes here
};
// Continue your logic but don't call then() method on your promise. Instead let's wait till your promise resolves
let res = await addHouseholdPromise;
console.log("Promise HH: "+res)
if (res != "add_hh_fail") {
return res;
}
else {
// Add to addHousehold array log
this.addHHArray(row)
// return something for else case as well
}
}
Notice that your function gets prefixed with a keyword called async
. This is important if you want to use the await
syntax to wait till the promise resolves.
Let's add async-await
keywords in main method as well to get the values.
async uploadDataV3(fromArray, toArray) {
// your logic goes here
let res = await this.addHousehold(row);
console.log('result: ', res);
}
Now your main method will also wait till the Promise is resolved and then gets the value which can be used for further processing.
Now in similar fashion, modify other methods as well to wait till the Promise resolves.
For more information on ES6 Promises and async-await keywords, refer this article.
来源:https://stackoverflow.com/questions/60524803/angular-8-why-the-promise-is-returning-an-undefined-value-despite-that-its-prop