Skip to main content

17.17 Fetching Orders via Redux

Orders.js

src\containers\Orders\Orders.js
import React, { Component } from "react";
import { connect } from "react-redux";
import axios from "../../axios-orders";
import Order from "../../components/Order/Order";
import Spinner from "../../components/UI/Spinner/Spinner";
import withErrorHandler from "../../hoc/withErrorHandler/withErrorHandler";
import * as actions from "../../store/actions/index";

class Orders extends Component {
componentDidMount() {
this.props.onFetchOrders();
}
render() {
let orders = <Spinner />;
if (!this.props.loading) {
orders = this.props.orders.map((order) => (
<Order
key={order.id}
ingredients={order.ingredients}
price={order.price}
/>
));
}
return orders;
}
}

const mapStateToProps = (state) => {
return {
orders: state.order.orders,
loading: state.order.loading,
};
};

const mapDispatchToProps = (dispatch) => {
return {
onFetchOrders: () => dispatch(actions.fetchOrders()),
};
};

export default connect(
mapStateToProps,
mapDispatchToProps
)(withErrorHandler(Orders, axios));

actionTypes.js

src\store\actions\actionTypes.js
export const ADD_INGREDIENT = "ADD_INGREDIENT";
export const REMOVE_INGREDIENT = "REMOVE_INGREDIENT";
export const SET_INGREDIENTS = "SET_INGREDIENTS";
export const FETCH_INGREDIENTS_FAILED = "FETCH_INGREDIENTS_FAILED";

export const PURCHASE_BURGER_START = "PURCHASE_BURGER_START";
export const PURCHASE_BURGER_SUCCESS = "PURCHASE_BURGER_SUCCESS";
export const PURCHASE_BURGER_FAIL = "PURCHASE_BURGER_FAIL";
export const PURCHASE_INIT = "PURCHASE_INIT";

export const FETCH_ORDERS_START = "FETCH_ORDERS_START";
export const FETCH_ORDERS_SUCCESS = "FETCH_ORDERS_SUCCESS";
export const FETCH_ORDERS_FAIL = "FETCH_ORDERS_FAIL";

actions/index.js

src\store\actions\index.js
export {
addIngredient,
initIngredients,
removeIngredient,
} from "./burgerBuilder";
export { fetchOrders, purchaseBurger, purchaseInit } from "./order";

actions/order.js

src\store\actions\order.js
import axios from "../../axios-orders";
import * as actionTypes from "./actionTypes";

export const purchaseBurgerSuccess = (id, orderData) => {
return {
type: actionTypes.PURCHASE_BURGER_SUCCESS,
orderId: id,
orderData: orderData,
};
};

export const purchaseBurgerFail = (error) => {
return {
type: actionTypes.PURCHASE_BURGER_FAIL,
error: error,
};
};

export const purchaseBurgerStart = () => {
return {
type: actionTypes.PURCHASE_BURGER_START,
};
};

export const purchaseBurger = (orderData) => {
return (dispatch) => {
dispatch(purchaseBurgerStart());
axios
.post("/orders.json", orderData)
.then((response) => {
console.log(response.data);
dispatch(purchaseBurgerSuccess(response.data.name, orderData));
})
.catch((error) => {
dispatch(purchaseBurgerFail(error));
});
};
};

export const purchaseInit = () => {
return {
type: actionTypes.PURCHASE_INIT,
};
};

export const fetchOrdersSuccess = (orders) => {
return {
type: actionTypes.FETCH_ORDERS_SUCCESS,
orders: orders,
};
};

export const fetchOrdersFail = (error) => {
return {
type: actionTypes.FETCH_ORDERS_FAIL,
error: error,
};
};

export const fetchOrdersStart = () => {
return {
type: actionTypes.FETCH_ORDERS_START,
};
};

export const fetchOrders = () => {
return (dispatch) => {
dispatch(fetchOrdersStart());
axios
.get("/orders.json")
.then((res) => {
const fetchedOrders = [];
for (let key in res.data) {
fetchedOrders.push({
...res.data[key],
id: key,
});
}
dispatch(fetchOrdersSuccess(fetchedOrders));
})
.catch((err) => {
dispatch(fetchOrdersFail(err));
});
};
};

reducers/order.js

src\store\reducers\order.js
import * as actionTypes from "../actions/actionTypes";

const initialState = {
orders: [],
loading: false,
purchased: false,
};

const reducer = (state = initialState, action) => {
switch (action.type) {
case actionTypes.PURCHASE_INIT:
return {
...state,
purchased: false,
};
case actionTypes.PURCHASE_BURGER_START:
return {
...state,
loading: true,
};
case actionTypes.PURCHASE_BURGER_SUCCESS:
const newOrder = {
...action.orderData,
id: action.orderId,
};
return {
...state,
loading: false,
purchased: true,
orders: state.orders.concat(newOrder),
};
case actionTypes.PURCHASE_BURGER_FAIL:
return {
...state,
loading: false,
};
case actionTypes.FETCH_ORDERS_START:
return {
...state,
loading: true,
};
case actionTypes.FETCH_ORDERS_SUCCESS:
return {
...state,
orders: action.orders,
loading: false,
};
case actionTypes.FETCH_ORDERS_FAIL:
return {
...state,
loading: false,
};
default:
return state;
}
};

export default reducer;