Skip to content

Commit

Permalink
Merge pull request #17 from lexich/async_helpers
Browse files Browse the repository at this point in the history
Add async helpers
  • Loading branch information
lexich committed Oct 2, 2015
2 parents e2bf2c0 + b3a1905 commit 285846b
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 19 deletions.
16 changes: 14 additions & 2 deletions README.md
Expand Up @@ -182,7 +182,8 @@ function (state, action) {

- @param **options.{endpoint}.helpers** - object
```js
{
{
logger: "/api/logger",
test: {
url: "/api/test/:name/:id",
helpers: {
Expand All @@ -194,16 +195,27 @@ function (state, action) {
const urlparams = {id, name};
const params = {body: {uuid, data}};
return [urlparams, params];
},
// complicated async logic
async() {
const {dispatch} = this;
return (cb)=> {
dispatch(rest.actions.logger((err)=> {
const args = [{id: 1, name: "admin"}];
cb(err, args);
}));
};
}
}
}
}
// using helpers
rest.actions.test.get(1, "admin");
// with callback
rest.actions.post(1, "admin", {msg: "Hello"}, (err)=> {
rest.actions.test.post(1, "admin", {msg: "Hello"}, (err)=> {
// end of action
});
rest.actions.test.async();
```

#### reduxApi object
Expand Down
2 changes: 1 addition & 1 deletion bower.json
@@ -1,6 +1,6 @@
{
"name": "redux-api",
"version": "0.6.4",
"version": "0.6.5",
"main": "dist/redux-api.min.js",
"dependencies": {}
}
28 changes: 24 additions & 4 deletions dist/redux-api.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/redux-api.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/redux-api.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/redux-api.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "redux-api",
"version": "0.6.4",
"version": "0.6.5",
"author": {
"name": "Efremov Alex",
"email": "lexich121@gmail.com",
Expand Down
33 changes: 25 additions & 8 deletions src/actionFn.js
Expand Up @@ -107,17 +107,34 @@ export default function actionFn(url, name, options, ACTIONS={}, meta={}) {
return fn(pathvars, modifyParams, callback)(dispatch, getState);
};
};
return reduce(meta.helpers, (memo, func, name)=> {

return reduce(meta.helpers, (memo, func, helpername)=> {
if (memo[helpername]) {
throw new Error(`Helper name: "${helpername}" for endpoint "${name}" has been already reserved`);
}
const {sync, call} = isFunction(func) ? {call: func} : func;
memo[name] = (...args)=> (dispatch, getState)=> {
memo[helpername] = (...args)=> (dispatch, getState)=> {
const index = args.length - 1;
const callback = isFunction(args[index]) ? args[index] : none;
const newArgs = fastApply(call, {getState}, args);
return fastApply(
sync ? fn.sync : fn,
null,
newArgs.concat(callback)
)(dispatch, getState);
const helpersResult = fastApply(call, {getState, dispatch}, args);

// If helper alias using async functionality
if (isFunction(helpersResult)) {
helpersResult((error, newArgs=[])=> {
if (error) {
callback(error);
} else {
fastApply(
sync ? fn.sync : fn, null, newArgs.concat(callback)
)(dispatch, getState);
}
});
} else {
// if helper alias is synchronous
fastApply(
sync ? fn.sync : fn, null, helpersResult.concat(callback)
)(dispatch, getState);
}
};
return memo;
}, fn);
Expand Down
49 changes: 49 additions & 0 deletions test/actionFn_spec.js
Expand Up @@ -342,4 +342,53 @@ describe("actionFn", function() {
]);
});
});
it("check incorrect helpers name", function() {
expect(
()=> actionFn("/test/:id", "test", null, ACTIONS, { helpers: { reset() {} }})
).to.throw(Error, `Helper name: "reset" for endpoint "test" has been already reserved`);
expect(
()=> actionFn("/test/:id", "test", null, ACTIONS, { helpers: { sync() {} }})
).to.throw(Error, `Helper name: "sync" for endpoint "test" has been already reserved`);
});
it("check helpers with async functionality", function() {
const meta = {
holder: {fetch(url, opts) {
return new Promise((resolve)=> resolve({url, opts}));
}},
helpers: {
asyncSuccess: ()=> (cb)=> cb(null, [{id: 1}, {async: true}]),
asyncFail: ()=> (cb)=> cb("Error")
}
};
const api = actionFn("/test/:id", "test", null, ACTIONS, meta);
const expectedEvent1 = [
{
type: ACTIONS.actionFetch,
syncing: false
}, {
type: ACTIONS.actionSuccess,
syncing: false,
data: { url: "/test/1", opts: { async: true }}
}
];
const wait1 = new Promise((resolve)=> {
api.asyncSuccess(resolve)(function(msg) {
expect(expectedEvent1).to.have.length.above(0);
const exp = expectedEvent1.shift();
expect(msg).to.eql(exp);
}, getState);
});
let errorMsg;
const wait2 = new Promise((resolve)=> {
api.asyncFail(function(err) {
errorMsg = err;
resolve();
})(function() {}, getState);
});
return Promise.all([wait1, wait2])
.then(()=> {
expect(expectedEvent1).to.have.length(0);
expect(errorMsg).to.eql("Error");
});
});
});

0 comments on commit 285846b

Please sign in to comment.