Reputation: 217
I am using Redux and Redux Saga for my project of an online shopping website, so this is how I have done:
actions/products.js
export const Types = {
GET_PRODUCTS_REQUEST: 'products/get_products_request',
GET_PRODUCTS_SUCCESS: 'products/get_products_success',
CREATE_PRODUCT_REQUEST: 'products/create_product_request',
};
export const getProductRequest = () => ({
type: Types.GET_PRODUCTS_REQUEST,
});
export const getProductSuccess = ({products}) => ({
type: Types.GET_PRODUCTS_SUCCESS,
payload: {
products,
},
});
export const createProductRequest = ({
name,
price,
description,
productImage,
}) => ({
type: Types.CREATE_PRODUCT_REQUEST,
payload: {
name,
price,
description,
productImage,
},
});
reducers/products.js
import {Types} from '../actions/products';
const INTIAL_STATE = {
products: [],
error: '',
};
export default function products(state = INTIAL_STATE, action) {
switch (action.type) {
case Types.GET_PRODUCTS_SUCCESS: {
return {
...state,
products: action.payload.products,
};
}
default: {
return state;
}
}
}
reducers/index.js
import {combineReducers} from 'redux';
import ProductsReducer from './products';
import OrderReducer from './orders';
export default combineReducers({
products: ProductsReducer,
orders: OrderReducer
});
sagas/products.js
import {takeEvery, call, fork, put, takeLatest} from 'redux-saga/effects';
import * as actions from '../actions/products';
import * as api from '../api/products';
function* getProducts() {
try {
const products = yield call(api.getProducts);
// console.log(products);
yield put(
actions.getProductSuccess({
products,
})
);
} catch (e) {}
}
function* watchGetProductRequest() {
yield takeEvery(actions.Types.GET_PRODUCTS_REQUEST, getProducts);
}
function* createProduct({name, price, description, productImage}) {
try {
yield call(api.createProduct, {
name,
price,
description,
productImage,
});
yield call(getProducts);
console.log('create products');
} catch (e) {
console.log(e, 'create products');
}
}
function* watchCreateNewProductRequest() {
yield takeLatest(actions.Types.CREATE_USER_REQUEST, createProduct);
}
const userSagas = [
fork(watchGetProductRequest),
fork(watchCreateNewProductRequest),
];
export default userSagas;
sagas/index.js
import {combineReducers} from 'redux';
import ProductsReducer from './products';
import OrderReducer from './orders';
export default combineReducers({
products: ProductsReducer,
orders: OrderReducer,
});
api/products
const baseUrl = 'https://shop-test-api.herokuapp.com';
export const getProducts = async () => {
return await (await (await fetch(`${baseUrl}/products`)).json()).docs;
};
export const createProduct = async ({
name,
price,
description,
productImage,
}) => {
return await fetch(`${baseUrl}/products`, {
method: 'POST',
body: {
name,
price,
description,
productImage,
},
headers: {
'content-type': 'application/json; charset=UTF-8',
},
}).json();
};
even I have not import createNewProductRequest
in the actions/products.js
to the component I want to use, the console log out this error:
The error occurs in the function createProduct
of sagas/products.js
, I use takeLastest
because I use many dispatches (create new product then take the updated product list after new product was created)
and it show me that error
please help me to tackle with it, it means a lot to me.
This is the code repo: https://gitlab.com/Khangithub/redux-saga-multiple-reducers-and-requests
Once again. thank you so much and have a good day
Upvotes: 4
Views: 7241
Reputation: 1729
Got the same error because I had a duplicate name across sagas
Upvotes: 0
Reputation: 129
Well, for me my action type was undefined, I changed the original file where I defined the types and forgot to effect the changes in my saga, hence that error. So that might be the same issue with your code. Just check your types to make sure its defined and there's no typos.
Upvotes: 13