Сегодня мы с Вами поговорим об асинхронных actions
. Мы начнем доставать наши статьи из API. Как вы могли заметить у нас уже работает простенький API для запуска которого нужно зайти в папку simple_api
, выполнить в ней команду:
npm install
для того, чтобы там появились свои node models
. После этого у Вас cработает скрипт который запускает несколько процессов одновременно, это видно в package.json
в корневой директории:
"scripts": { "start": "concurrently \"npm run dev\" \"npm run api\"", "api": "node simple_api/server.js", "dev": "webpack-dev-server --hot --inline", "build": "webpack" },
В нашем случае он запускает одновременно npm run dev
и npm run api
. Один поднимает API а другой запускает webpack dev server
. С этих пор у нас на порту 3001
работает простая API:
http://localhost:3001/api/article
а на порту:
http://localhost:8080
– developer’s server.
В реальной жизни часто так и происходит, когда разработкой API занята другая команда, с которой вы можете встречаться достаточно редко. API может находиться у Вас где угодно: локально, удаленно, это не важно. Где-то работает Ваше API, а где-то локально работает Ваш dev server
. Посмотрите на webpack.config.js
:
devServer: { proxy: [{ path: '/api/*', target: 'http://localhost:3001' }]
В webpack
devServer
. Вам нужно будет настроить переадресацию, чтобы не было никаких сrossdomain
запросов. Все что у нас приходит на /api
будет проксироваться на вашу API. Сейчас это localhost:3001
, а далее это может какой-нибудь удаленный адрес. Вы делаете переадресацию и по обоим адресам у Вас будет доступ до article
:
http://localhost:3001/api/article
http://localhost:8080/api/article
Таким образом все то, что будет приходить на localhost:8080
будет попадать на Вашу страницу, а все что приходит на /api
будет переадресовываться на Вашу API.
Мы с Вами хотим получать все наши статьи не из fixtures.js
, а из API, как в реальной жизни. давайте это реализуем. Сейчас по api\article\
у нас отдаются все статьи без текстов, и комментариев. Т.к. получать все данные сразу не имеет никакого смысла, потому что они могут быть достаточно большими. Также комментарии нам придется получать с помощью дополнительного запроса, тогда, когда они нам понадобятся.
Для начала получим список статей из API и отобразим их по привычному адресу:
http://localhost:8080
Для этого сначала установим JQuery. Установим мы его исключительно для того, чтобы делать AJAX
запросы, наберите в console
:
npm i jquery --s
Нам нужно сделать запрос на api\article\
. Запросы мы будем делать в middleware
т.к. запросы это Side Effect.
Создадим файл /middlewares/api.js
.
Сразу же нужно сказать о том, что мы будем разбивать наши actions
на START
, SUCCESS
, FAIL
. Зайдем в constants.js
и добавим следующую запись:
export const LOAD_ALL_ARTICLES = 'LOAD_ALL_ARTICLES' export const START = '_START' export const SUCCESS = '_SUCCESS' export const FAIL = '_FAIL'
Мы берем action
LOAD_ALL_ARTICLES
и далее добавляем к нему наши константы в зависимости от того, приходит к нам запрос или нет. Вернемся к /middlewares/api.js
и сделаем import
JQuery библиотеки и наших констант:
import $ from 'jquery' import { START, SUCCESS, FAIL } from '../constants'
По аналогии с randomID.js
где мы проверяли наличие флажка withRandomId
мы сделаем с API. Мы создадим action creator
, который будет называться LOAD_ALL_ARTICLES
в AC/articles.js
:
import { DELETE_ARTICLE, LOAD_ALL_ARTICLES } from '../constants' export function deleteArticle(id) { return { type: DELETE_ARTICLE, payload: { id } } } export function loadAllArticles() { return { type: LOAD_ALL_ARTICLES, callAPI: '/api/article' } }
Возвращать мы будем такой же плоский объект. И у него будет флажок callAPI
(ключ) и значение в виде /api/article
. Теперь в middleware
мы будем проверять, если у action
будет callAPI
значит это тот который нас интересует, если нет то мы будем пропускать его дальше.
Продолжим пиcать логику в /middlewares/api.js
:
import $ from 'jquery' import { START, SUCCESS, FAIL } from '../constants' export default store => next => action => { const { callAPI, type, ...rest } = action if (!callAPI) return next(action) next({ type: type + START, ...rest }) $.get(callAPI) .done(response => next({type: type + SUCCESS, response, ...rest})) .fail(error => next({type: type + FAIL, error, ...rest})) }
Как видно из кода выше, если мы не получаем флажок в виде callAPI
мы просто передаем управление дальше. Если же он есть, то мы будем делать JQuery GET
запрос. Прежде чем сделать обращение, мы с Вами передадим управление дальше, сказав, что мы начинаем загрузку. В .done
, когда к нам придет ответ, мы возьмем его и передадим управление дальше. Наш type
уже будет выглядеть как type + SUCCESS
также мы с Вами передадим здесь response
и все остальное. Т.к. наш action
может пройти через несколько middleware
, например через randomID
а потом через callAPI
. Также поступим и с .fail
. В итоге у нас action
поделился на два action
.
We are looking forward to meeting you on our website soshace.com