Angular 8, почему обещание возвращает неопределенное значение, несмотря на то, что оно должным образом утешается непосредственно перед разрешением? - PullRequest
0 голосов
/ 04 марта 2020

РЕДАКТИРОВАТЬ

Я утешил, если скрипт входит в addHousehold (), если условие в:

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)

      }
    })

И оно вернуло значение, но когда я перехватил это в основной функции, это становится undefined.

КОНЕЦ РЕДАКТИРОВАНИЯ

Исходное сообщение

У меня есть основной функция, которая l oop над массивом fromArray, и она берет каждую строку этого и делает следующее:

  1. добавляет доменное имя в базу данных, используя this.api.postData(array);
  2. Регистрация в программе program_from
  3. После регистрации мы go переходим в другой l oop до l oop поверх другого массива toArray, который будет содержать членов, и добавляем членов, которые связаны строки fromArray и имеют следующее условие:

    if (row_hh ['hh_new_id'] == row_mbr ['hh_new_id'])

  4. После добавления связанных членов, мы регистрируем их в другую программу program_to;

  5. В конце мы берем каждый hh_id и каждый связанный mbr_id и соединяем их через addRelation().

** I. Основной метод: **

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);
            }
          }
        })
      }
    });
  }

Основная проблема теперь заключается в этой строке:

hh_id = this.addHousehold(row_hh);
console.log('HH ID: '+hh_id)

возвращаемое значение равно undefined, как показано на рисунке ниже:

enter image description here

При методе addHousehold() показывается сгенерированный идентификатор registered_hh_id:

console.log("check hh_id", this.registered_hh_id);

enter image description here

Даже при обещании функции:

addHouseholdPromise.then((res) => {
  console.log("Promise HH: "+res)
  if (res != "add_hh_fail") {
    return res;
  }
  else {
    // Add to addHousehold array log
    this.addHHArray(row)

  }
})

Эта строка показывает возвращенный идентификатор:

console.log("Promise HH: "+res)

Так что проблема в том, что внутри метод add Household получает идентификатор с сервера, но возвращает его как undefined.

Вот подробные методы, используемые также в основной функции

II. Для дополнительного хозяйства:

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. Зачисление в домохозяйство: **

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. После регистрации мы добавим участника: **

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. После добавления участника мы регистрируем его в программе: **

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. И в конце мы добавляем отношение между hh_id и всеми связанными с ним 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 Ответ

1 голос
/ 04 марта 2020

Вы возвращаете значение, используя ключевое слово return в then() методе обратного вызова Promises. Это не сработает. Функция, которую вы передаете внутрь then(), будет выполнена когда-нибудь в будущем, когда обещание будет выполнено. Поэтому, если вы хотите подождать, пока ваше обещание разрешится, чтобы получить значение, используйте подход ES6 async-await.

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
    }
}

Обратите внимание, что вашей функции присваивается префикс с ключевым словом async. Это важно, если вы хотите использовать синтаксис await для ожидания разрешения обещания.

Давайте также добавим async-await ключевых слов в метод main, чтобы получить значения.

async uploadDataV3(fromArray, toArray) {
  // your logic goes here
  let res = await this.addHousehold(row);
  console.log('result: ', res);
}

Теперь ваш основной метод также будет ждать разрешения Обещания и затем получит значение, которое можно использовать для дальнейшей обработки.

Теперь аналогичным образом измените и другие методы, чтобы дождаться разрешения Обещания.

Подробнее о обещаниях ES6 и asyn c -wait ключевых словах см. В статье article .

.
...