Home > Net >  How to make Javascript wait for a Promise before sending a request?
How to make Javascript wait for a Promise before sending a request?

Time:11-10

I know there are many questions and answers based on Promise, but what I want to do is to retrieve some data with axios (to a microservice) and then to use this data in order to send another request (to a different microservice).

Somehow, I figured out how to set my request:

screenshot from console with the request right before axios call

The problem is that in backend I have only first two clauses. I think this is because I have used async/await in order to successfully avoid Promise and get the actual result/class. What I meant is that, maybe the request is sent before the promise is fulfilled, but how do I correctly get the request in console?

I am newbie into Javascript, so any helping hand is welcome.

EDIT:

Here is my code:

getServicesList = async (instanceIds) => {
    return await FlowsInventoryAPI.searchServices(instanceIds, this.props.salesline, this.props.environment, this.props.sources, this.props.targets)
        .then((response) => {
            return response;
        })
        .catch((error) => {
            Toastr.error(ResponseErrorProvider.getError(error));
            if (ResponseErrorProvider.isUnauthorized(error)) {
                Toastr.error(error.response.data.message);
                this.props.onLogout();
            }
        });
}

The above one is the first call I've talked about.

buildSearchObject = (size, page, status) => {
        let interval = TimestampUtils.getInterval(this.props.logsTimeInterval);
        let from = interval.from * 1000;
        let to = interval.to * 1000;
        
        return {
            fromMillis: from,
            toMillis: to,
            size: size,
            page: page,
            salesline: this.props.salesline,
            environment: this.props.environment,
            routes: this.props.routes,
            sources: this.props.sources,
            targets: this.props.targets,
            customFilters: [...this.props.filters.values(), ...this.getEnabledAdvancedFilters().values()],
            status: status === LogStatus.ALL ? "" : status,
            sortFieldName: this.props.sortColumn,
            order: this.props.sortOrder,
            searchFilter: this.props.searchFilter,
            searchFilterOperator: this.props.searchFilterOperator,
            applications: this.props.applications,
            openedStores: this.props.openedStores,
            servicesPromise: this.state.servicesList // here is the promise
        }
    };
searchLogs = (size, page, status, callback) => {
        loadingService.showLoadingModal("loadingLogsPage", this.props.location.pathname);
        let searchObject = this.buildSearchObject(size, page, status);
        ElasticSearchApi.search(searchObject, this.props.token)
            .then(response => {
                callback(response);
            })
            .catch((error) => {
                loadingService.hideLoadingModal("loadingLogsPage", this.props.location.pathname);
                Toastr.error(ResponseErrorProvider.getError(error));
                if (ResponseErrorProvider.isUnauthorized(error)) {
                    Toastr.error(error.response.data.message);
                    this.props.onLogout();
                }
            });
    };

I have the second call in last paragraph which calls the buildSearchObject method which contains our promise. As I told you I figured out how to send it as value, but I think that because of "asynchronicity" maybe my promise is not ready yet in the moment when second call is called, this is why my code has the promise in state.

EDIT 2:

 constructor(props) {
        super(props);
        this.ongoingRequestId = undefined;
        this.ongoingRequests = new Map();
        this.state = {
            servicesList: this.getServicesList(this.getInstanceIds())
        }
    }

Here is my constructor, where I create my this.state.servicesList.

CodePudding user response:

Some advice:

  • Do not mix traditional promises syntax with async / await. It will make your code hard to understand, even for yourself. Do not mix either callback approach with promises. Choose one approach and stick to it.
  • If you are having a hard time with promises, force yourself to use async / await everywhere. async / await is easier to understand in my opinion, because it doesn't break your code flow.

For instance, transform this:

FlowsInventoryAPI.searchServices(/* params */)
  .then((response) => /* response code */)
  .catch((error) => /* error code */)

to:

try {
  const response = await FlowsInventoryAPI.searchServices(/* params */);
  /* response code */
} catch (error) {
  /* error code */
}
  • Do not make your constructors asynchronous like you do where you call this.getServicesList, because you cannot wait for an asynchronous operation (like getServicesList) inside a constructor. Use instead a static async method.

For instance, transform this:

class SomeObject extends Something {
  constructor(props) {
    super(props);
    this.ongoingRequestId = undefined;
    this.ongoingRequests = new Map();
    this.state = {
      servicesList: this.getServicesList(this.getInstanceIds())
    }
  }
}

to:

class SomeObject extends Something {
  constructor(props) {
    super(props);
    this.ongoingRequestId = undefined;
    this.ongoingRequests = new Map();
    this.state = { servicesList: null };
  }

  async init() {
    this.state.servicesList = await this.getServicesList(this.getInstanceIds());
  }

  static async create(props) {
    const someObject = new SomeObject(props);
    await someObject.init();
    return someObject;
  }
}

Instead of calling const object = new SomeObject(props);, do const object = await SomeObject.create(props);

CodePudding user response:

You will need to use await keyword to wait for a promise response before continuing.

  // 1. Wait for create or update the customer before continuing
  const customerId = await updateOrCreateCustomer(customerData);

  // 2. Register sale, with customer created in previous section
  const customerSale = sale(paymentMethod, customerId);

Read more about the await keyword

  • Related