Search code examples
javascripttypescriptpromisees6-promise

Trouble with Promises completing


The user will click a button which will call:

private _saveJobCreate(): void {
  if ((this.state.jobToCreate.TruckLookUpId && this.state.jobToCreate.TruckLookUpId !== undefined) &&
    (this.state.jobToCreate.DeliveryDate && this.state.jobToCreate.DeliveryDate.length > 0)) {
    console.log("valid input, should save");

    this._createJob(this.state.jobToCreate)
      .then(() => {
        console.log("job created and should be fetched, hiding panel");
        this._hideJobCreatePanel();
      });
  }
}

Which calls this method:

private _createJob(newJob: IDeliveryJob): Promise < void > {
  console.log("creating job");
  let promise: Promise < void > = new Promise < void > ((resolve, reject) => {
    this.props.deliveryJobService.createJob(newJob)
      .then(() => {
        console.log("job created, fetching jobs");
        this._fetchJobs()
          .then(() => {

          });
      });
  });
  return promise;
}

Which will fetch my jobs from a Sharepoint list:

private _fetchJobs(): Promise < void > {
  console.log("fetching jobs");
  let promise: Promise < void > = new Promise < void > ((resolve, reject) => {
    this.props.deliveryJobService.getDeliveryJobs()
      .then((newJobs: IDeliveryJob[]) => {
        console.log("jobs fetched, setting state");
        this.setState({
          jobs: newJobs
        });
      });
  });
  return promise;
}

The issue is it stops at setting the state, the last console.log I see is:

fetching jobs DeliveryJobService.ts:59 response.json: ƒ (){return this.nativeResponse.json()} DeliveryJobService.ts:63 response.value: (24) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] TruckDeliverySchedule.tsx:503 jobs fetched, setting state

So, it looks like the last method _fetchJobs() is not returning its Promise so the first method can call _hideJobCreatePanel().

I'm pretty new with typescript/javascript development and I can't figure out why the last Promise isn't being return.


Solution

  • You're never resolve or reject -ing any of you're promises, and what's more you've fallen into the anti-pattern of a wrapping perfectly good promises in your own Promise.

    For example, instead of this:

    private _fetchJobs(): Promise<void> {
        console.log("fetching jobs");
        let promise: Promise<void> = new Promise<void>((resolve, reject) => {
          this.props.deliveryJobService.getDeliveryJobs()
          .then((newJobs: IDeliveryJob[]) => {
            console.log("jobs fetched, setting state");
            this.setState ({
              jobs: newJobs
            });
          });  
        });
    
        return promise;
    }
    

    you should do this:

    private _fetchJobs(): Promise<void> {
        console.log("fetching jobs");
        return this.props.deliveryJobService.getDeliveryJobs()
          .then((newJobs: IDeliveryJob[]) => {
            console.log("jobs fetched, setting state");
            this.setState ({
              jobs: newJobs
            });
          });  
    }
    

    When you do this in _createJob don't forget to return the chained promise:

     private _createJob(newJob: IDeliveryJob): Promise<void> {
        console.log("creating job");
        return this.props.deliveryJobService.createJob(newJob)
          .then(() => {
            console.log("job created, fetching jobs");
            return this._fetchJobs() // HERE!
              .then(() => {
    
              });
          });  
      }
    

    Each of your methods should return the promise, not wrap it in a new one, and then your problem will no longer exist... and what's more you can just chain your calls, which makes the code more readable.