{"id":20936809,"url":"https://github.com/aruntk/redux-api-saga","last_synced_at":"2025-05-13T21:31:12.359Z","repository":{"id":34080895,"uuid":"169398455","full_name":"aruntk/redux-api-saga","owner":"aruntk","description":"Redux API Saga - REACT API calls made simple","archived":false,"fork":false,"pushed_at":"2022-12-03T22:57:18.000Z","size":55,"stargazers_count":18,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-03T16:03:23.032Z","etag":null,"topics":["api","react","redux","redux-saga","saga"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aruntk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-06T11:52:38.000Z","updated_at":"2019-12-02T04:03:35.000Z","dependencies_parsed_at":"2023-01-15T04:30:55.081Z","dependency_job_id":null,"html_url":"https://github.com/aruntk/redux-api-saga","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aruntk%2Fredux-api-saga","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aruntk%2Fredux-api-saga/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aruntk%2Fredux-api-saga/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aruntk%2Fredux-api-saga/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aruntk","download_url":"https://codeload.github.com/aruntk/redux-api-saga/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254030950,"owners_count":22002676,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","react","redux","redux-saga","saga"],"created_at":"2024-11-18T22:27:07.223Z","updated_at":"2025-05-13T21:31:12.330Z","avatar_url":"https://github.com/aruntk.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# redux-api-saga\n\nREACT API calls made simple\n\n\u003cdiv\u003e \n\u003ca href=\"https://www.npmjs.com/package/redux-api-saga\"\u003e\n    \u003cimg\n      src=\"https://img.shields.io/npm/v/redux-api-saga.svg\" height=\"20\"\u003e\n  \u003c/a\u003e\n     \u003ca href=\"https://www.npmjs.com/package/redux-api-saga\"\u003e\n    \u003cimg\n      src=\"https://img.shields.io/npm/dt/redux-api-saga.svg\" height=\"20\"\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n\u003c/div\u003e\n\nIts an abstraction on top of redux-saga. Takes in a config and gives you a reducer saga and a common action. \n\n### Setup\n\n```js \n// store.js\nimport init from 'redux-api-saga';\nimport { applyMiddleware, createStore } from 'redux';\nimport createSagaMiddleware from 'redux-saga';\nimport { all } from 'redux-saga/effects';\n\nconst defaultOnSuccess = (result) =\u003e {\n  console.log(typeof result === 'string' ? result : 'Successful.' );\n};\nconst defaultOnError = (error) =\u003e {\n  alert(typeof error === 'string' ? error : error.message);\n};\nconst config = [\n  {\n    path: 'http://localhost:3001/auth',\n    method: 'POST',\n    name: 'authToken', // API will be referred in action using this name\n    mode: 'takeLatest',\n    initialResult: null, // this is the initial value,\n    onSuccess: defaultOnSuccess,\n    onError: defaultOnError,\n  },\n  {\n    path: 'http://localhost:3001/puppyJpg/:imageId',\n    method: 'GET',\n    name: 'puppyJpg',\n    mode: 'takeLatest',\n    initialResult: 'https://upload.wikimedia.org/wikipedia/commons/9/9c/Indian_pariah_dog_puppy_%288334906336%29.jpg',\n  },\n];\n// default set of headers. you can choose to override this in every action dispatch. \nconst getReqHeaders = (state) =\u003e ({\n  Authorization: `bearer ${state.authToken}`,\n});\nconst options = {\n  getReqHeadersDefault: getReqHeaders,\n};\nconst apiSaga = init(config, options);\n\nconst reducer = apiSaga.reducer;\nconst sagas = apiSaga.sagas;\nexport const action = apiSaga.action;\nfunction* saga() {\n  yield all(sagas);\n}\n\n// create middlewares\nconst sagaMiddleware = createSagaMiddleware();\nconst middleware = applyMiddleware(sagaMiddleware);\n// create store\nconst store = createStore(reducer, middleware);\nexport default store;\n// run saga middleware\nsagaMiddleware.run(saga);\n```\n\n### Usage\n\n```js\n// auth.jsx\n\nimport { action } from './store';\n\n...\n\nlogin(username, password) {\n  this.props.dispatch(action({\n    name: 'authToken',\n    payload: { username, password }, // this will be passed as req.body of the XHR call\n    getReqHeaders: () =\u003e ({}) // override default header,\n  }));\n}\n```\n\n```js\n// puppy.jsx\nimport { action } from './store';\n\n...\n\nclass PuppyImg extends React.Component {\n  state = {};\n  getPuppyImg = () =\u003e {\n    this.props.dispatch(action({\n      name: 'puppyJpg',\n      payload: {},\n      params: { imageId: 20345 }, // this will replace the param :imageId\n      query: { resolution: 'HD' },\n      // You can override success and error hooks\n      onSuccess: () =\u003e {},\n      onError: (error) =\u003e {\n        console.error(typeof error === 'string' ? error : error.message);\n      };\n    }));\n    // resultant API path -\u003e http://localhost:3001/puppyJpg/20345?resolution=HD\n  }\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.getPuppyImg}\u003e\n          Test\n        \u003c/button\u003e\n        \u003cimg src={this.props.puppyJpg} /\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n \nconst mapState = (state) =\u003e ({\n  puppyJpg: state.puppyJpg,\n});\n \nexport default connect(mapState)(PuppyImg);\n```\n\n### Cancel a request\n\nUse `onDispatch` hook to get the cancel function\n\nexample -\u003e \n\n```js\nclass PuppyImg extends React.Component {\n  cancelRequest = null\n  getPuppyImg = () =\u003e {\n    this.props.dispatch(action({\n      name: 'puppyJpg',\n      payload: {},\n      params: { imageId: 20345 }, // this will replace the param :imageId\n      query: { resolution: 'HD' },\n      onDispatch: (cancel, state, payload) =\u003e {\n        this.cancelRequest = cancel;\n      }\n    }));\n    // resultant API path -\u003e http://localhost:3001/puppyJpg/20345?resolution=HD\n  }\n  cancelPuppyImgCall = () =\u003e {\n    this.cancelRequest \u0026\u0026 this.cancelRequest()\n  }\n  // Now call cancelPuppyImgCall in case you want to give user an option to cancel the request\n```\n\n### Reset state\n\n```js\nthis.props.dispatch(action({\n    name: 'puppyJpg',\n    reset: true,\n    // if resetPayload is not empty then the state is set to that otherwise to the initialState\n    // resetPayload: 'https://upload.wikimedia.org/wikipedia/commons/9/9c/Indian_pariah_dog_puppy_%288334906336%29.jpg'\n}))\n\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faruntk%2Fredux-api-saga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faruntk%2Fredux-api-saga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faruntk%2Fredux-api-saga/lists"}