retrieve the promise from the store following the dispatch of the redux thunk

I need help understanding how to properly chain dispatches with Redux Thunk

function createSimpleAction(){
  return {type: "SIMPLE_ACTION"}
}

export function createAsyncAction(){
  return function(dispatch, getState){
    return dispatch(createSimpleAction).then(()=>{...});
  }
}

Is there a way to get the dispatch to return a promise from the store?

MORE SPECIFICALLY:

It seems like most examples using redux-thunk involve calling an async event (such as fetch) which returns a Promise.

Specifically, I'm wondering about ensuring that the store has fully processed an action before proceeding in the action_creator() function above.

I would prefer if the store could somehow return a promise, but I'm unsure of how or where this should be implemented?

Answer №1

If you're looking for an example of how to handle asynchronous actions in Redux, check out this link: https://github.com/gaearon/redux-thunk

The thunk middleware simplifies the process of turning async thunks into regular actions. Your "simple_action()" function needs to be a thunk, which is essentially a function that returns another function. Here's an example:

function makeASandwichWithSecretSauce(forPerson) {
  return function (dispatch) {
    return fetchSecretSauce().then(
      sauce => dispatch(makeASandwich(forPerson, sauce)),
      error => dispatch(apologize('The Sandwich Shop', forPerson, error))
    );
  };
}

You can then use the `dispatch` function with `makeASandwichWithSecretSauce()` like this:

store.dispatch(
  makeASandwichWithSecretSauce('Me')
);

You can also chain promises by returning them from your dispatched thunks:

store.dispatch(
  makeASandwichWithSecretSauce('My wife')
).then(() => {
  console.log('Done!');
});

This approach allows you to create action creators that handle both synchronous and asynchronous actions smoothly.

function makeSandwichesForEverybody() {
  return function (dispatch, getState) {
    if (!getState().sandwiches.isShopOpen) {
      return Promise.resolve();
    }

    dispatch(simple_action());

    return dispatch(
      makeASandwichWithSecretSauce('My Grandma')
    ).then(() =>
      Promise.all([
        dispatch(makeASandwichWithSecretSauce('Me')),
        dispatch(makeASandwichWithSecretSauce('My wife'))
      ])
    ).then(() =>
      dispatch(makeASandwichWithSecretSauce('Our kids'))
    ).then(() =>
      dispatch(getState().myMoney > 42 ?
        withdrawMoney(42) :
        apologize('Me', 'The Sandwich Shop')
      )
    );
  };
}

store.dispatch(
  makeSandwichesForEverybody()
).then(() =>
    console.log("Done!");
);

To manage the sequence of actions in action_creator(), it can be helpful to dispatch a simple_action before calling `action_creator()`. This ensures that the store processes the action completely before moving on to the next steps.

Answer №2

Lately, I've been implementing this particular pattern:

const processData = data => (dispatch, getState) => Promise.resolve().then(() => {
  const { currentData } = getState();
  return dispatch({
    type: actionTypes.PROCESS_DATA,
    data,
  });
});

Upon calling

dispatch(processData('some-data'))
, a Promise will be returned allowing for additional actions to be chained.

Answer №3

In situations where you want to chain certain activities using the `dispatch` function, it is important that your action returns a `Promise`. This way, `dispatch` will return whatever the action/function calls.

If your action is implemented as a `thunk`, you can structure it in such a way that it returns a `Promise`, enabling you to achieve the desired chaining of activities.

On a side note, naming your `thunk` as `action_creator` may create confusion, as `simple_action` is actually considered an Action Creator in Redux terminology - hence the recommendation for proper naming conventions.

Answer №4

Exploring asynchronous actions and invoking an action from a component with the use of redux in conjunction with thunk

Executing Without Promise

action.js

export function shareForm(id) {
    return function (dispatch) {
        dispatch({
            type: 'SHARE_FORM',
            payload: source.shareForm(id)
        })
    }
}

SomeComponent.js

dispatch(shareForm(id))

Implementing With Promise

action.js

export function shareForm(id, dispatch) {
    return new Promise((resolve, reject) => {
        dispatch({
            type: 'SHARE_FORM',
            payload: source.shareForm(id)
        })
          .then(res => resolve(res))
          .catch(err => reject(err))
    })
}

SomeComponent.js

shareForm(id, dispatch)
  .then(res => console.log('log on success', res))
  .catch(err => console.log('log on failure', err))

PS: Feel free to ask for further clarifications in the comments section

Answer №5

To accomplish this task, you will need to create a truncate action that returns a Promise. The dispatch function will return whatever you have added as an argument in its call. For instance, if you want the dispatch to return a Promise, you must include Promise as an argument in the call.

function simple_action() {
  return { type: 'SIMPLE_ACTION' };
}

export function async_action(dispatch, getState) {
  return function () {
    return Promise.resolve(dispatch(simple_action()));
  }
}

const boundAction = async_action(dispatch, getState);
boundAction().then(() => {});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Gathering feedback from a webpage using JavaScript and jQuery

I have been experimenting with different tools such as Selenium and BeautifulSoup in an attempt to scrape the contents of the following website/pages: . Specifically, I am looking to extract the reviews/sections which are dynamically loaded by JS, jQuery ...

Replacing text in a file using AJAX, JS, and PHP and sending it to a PHP file with successful attribute included

Within my code, there is a button identified by the ID genPDF that triggers the following function upon being clicked: $('#genPDF').click(function () { var str = "headingText=" + jQuery("#headingText").val(); $.ajax({ url: &apo ...

Exploring the functions of storage markers and center maps in Google Maps API

I created a form on a webpage to add markers to Google Maps and center the map. However, every time I refresh the browser, all my changes disappear. What options do I have to ensure that these changes are persistent? (Note: I prefer not to use cookies). ...

What are some alternatives to using Switch Statements in VueJS filter component?

Recently, I developed a Vue Component that incorporates a simple filter feature using BootstrapVue. My query pertains to JavaScript Switch Statements - it is common knowledge that they may not always be the most optimal choice due to potential debugging c ...

Interactive data visualization with hover-over details

I am utilizing datamaps to showcase the countries of the world, however, I want the graph to be centered. The issue arises when I hover over a country and the pop up appears all the way to the left, aligned with where the country would be if it wasn't ...

Utilizing Angular's binding feature with objects

Clarifying the question for better understanding. Plunkr Preview: <input type="text" ng-model="form['data']['sampleData']"> <input type="text" ng-model="form[bindingPrefix][bindingSuffix]"> <input type="text ...

HTMLMediaElement does not have the setSinkId method

I am currently in the process of developing a WebRTC application using Angular, with the goal of managing audio output through the setSinkId() method within HTMLMediaElement. However, when attempting to use this method, I am encountering an error message s ...

"Utilizing Node's Res.write to transmit a stream of various objects

I am encountering an issue while attempting to send multiple objects in the response as JSON back to the client from a single route. This involves a middleware that is triggered, which then internally calls another route to fetch data and perform some proc ...

Performing multiple Cypher queries from Node.js with Neo4j

Struggling to execute multiple Cypher queries in Neo4j? Need the results back in JSON format for each query? Here is a sample code snippet that might help: var array=[]; var ftrend= [ '21', '23', '24', '41', '4 ...

The step-by-step guide on displaying API choices in an Autocomplete feature and keeping them up

Having trouble with updating autocomplete options. An error message pops up in the console log when I try to deselect a tag or select a new one: MUI: The value provided to Autocomplete is invalid. None of the options match with [{"catName":{&qu ...

Can we dynamically assign types to portions of a TypeScript interface?

I'm looking for a way to extend a TypeScript object with a specific type. Here's an example scenario: interface BaseInterface<T> { staticA: string; staticB: number; dynamicA: T; } BaseInterface<SomeOtherInterfaceOrType> When u ...

Utilizing HTML and JavaScript to add grayscale effect to images within a table, with the ability to revert to the colored version upon mouseover

Seeking advice on utilizing the mouseover / mouseout event in javascript to implement grayscale on a table. The challenge requires creating a gray image grid (table) using HTML and then incorporating Javascript so that hovering over an image triggers it to ...

How to Transfer Data from One View to Another Controller in MVC using ASP .NET

I need to pass the selected index of a dropdownlist in my View to a different controller. I have successfully retrieved the index using JavaScript. However, I am now looking for a way to send this index to another Controller upon clicking my button. Coul ...

Preloading jQuery Images in Relation to the Present Document

I am looking to create a custom jQuery image preloader that dynamically loads images based on the current document. My plan is to use a jQuery script that combines the current document name and an adjustable imagename/extension. For example, if the curre ...

What is the process to transfer data from JavaScript to HTML within a Laravel environment?

I am attempting to transfer a value from JavaScript to HTML as a variable. In order to do this, I am retrieving the value from a Laravel PHP controller. JavaScript $("ul.nav-tabs > li > a").click(function() { var id = $(this).attr("href").repla ...

Looking forward to the nested forEach functionality

Can you explain why this code snippet behaves unexpectedly? const firstArray = ['toto', 'toto']; const secondArray = ['titi', 'titi']; firstArray.forEach(async (toto, i) => { await secondArray.forEach(async tit ...

leveraging an array from a separate JavaScript file within a Next.js page

I am facing a situation where I need to utilize an array from another page within my Next.js project. However, it seems that the information in the array takes time to load, resulting in encountering undefined initially when trying to access it for title a ...

Is it possible to create cloud functions for Firebase using both JavaScript and TypeScript?

For my Firebase project, I have successfully deployed around 4 or 5 functions using JavaScript. However, I now wish to incorporate async-await into 2 of these functions. As such, I am considering converting these specific functions to TypeScript. My conc ...

Tips for customizing plupload to prompt the user for a file title

I have successfully implemented plupload on my website to allow users to upload photos, and I am also using the jQuery queue widget. My current server method only accepts the filename, chunk, and content of the photo. Is there a way for users to specify a ...

Exploring attributes within designated namespaces using jQuery

If I have a document structured like this: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de"> <body> ... </body> Is there a way to extract the value of the xml:lang attribute using jQuery? I know how to select elements with ...