-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question about child.call and returned value #94
Comments
@paulcookie sorry it took me so long to respond. 😞 Could you provide a code snippet? ...so I can more clearly see what you want/wanted to do. It would also be cool to see what you came up with! |
wow, thanks for reply, even if it took a long time.. Postmate could do things like this: but if we need to pass some arguments to child method and get returned promise we can't do this easily, we should use event emitter:
so basically I wanna do things like this:
in this case we don't need to create and name custom events |
@yowainwright is there a reason why the 'call' method does not return a Promise in the same way that the 'get' method does? This could be useful if you want to both (1) pass data across and (2) validate or do something with the response you’re given. Looking at the code it seems like things could be simplified so 'call' and 'get' use the same API, e.g., if it passed any /**
* Takes a model, and searches for a value by the property
* @param {Object} model The dictionary to search against
* @param {String} property A path within a dictionary (i.e. 'window.location.href')
* @param {Object} data Additional information from the get request that is
* passed to functions in the child model
* @return {Promise}
*/
export const resolveValue = (model, property, data) => {
const unwrappedContext = typeof model[property] === 'function'
? model[property](data) : model[property]
return Postmate.Promise.resolve(unwrappedContext)
} (NOTE: strangely EDIT: I’m seeing in the test code an example that does a call, immediately followed by a get, which seems like it could work, but it still seems odd to me that we can’t just get a response from 'call'? https://github.com/dollarshaveclub/postmate/blob/master/test/acceptance/test.js#L50 |
Just stumbled upon this as well. It seems a little bit strange, that However, here is my solution to the problem for now (based on @mrcoles observation): // Save to postmate-async-func.js
/* Creates a function property that takes arguments and returns a promise */
export function makeAsyncFunctionProperty(func) {
let cachedArgs = null;
return (args) => {
if ( args !== undefined ) {
cachedArgs = args;
} else {
return func(cachedArgs).catch(e => new Error(e)); // Does not inclued stack trace
}
}
}
/* Enhances ParentAPI with new method "callAsync" */
export function enhanceChildAsyncCall(child) {
child.callAsync = (fname, data) => {
child.call(fname, data || null);
return Promise.resolve(child.get(fname)).then(res => {
if ( res instanceof Error ) {
throw res;
}
return res;
});
};
return child;
} The two functions can then be used like this to create async functions that take arguments: // Your model
import { makeAsyncFunctionProperty } from './postmate-async-func'
const handshake = new Postmate.Model({
asyncMult: makeAsyncFunctionProperty((value) => {
let result = value * 5;
return new Promise((resolve) => {
setTimeout(() => resolve(result), 1000)
})
}),
asyncAdd: makeAsyncFunctionProperty((value) => {
let result = value + 5;
return new Promise((resolve) => {
setTimeout(() => resolve(result), 1000)
})
}),
asyncFail: makeAsyncFunctionProperty((value) => {
return Promise.reject()
}),
} // Your parent
import { enhanceChildAsyncCall } from './postmate-async-func'
handshake.then(child => {
enhanceChildAsyncCall(child);
child.callAsync('asyncMult', 4).then(res => {
console.log("Got result", res)
});
child.callAsync('asyncAdd', 3).then(res => {
console.log("Got result", res)
});
child.callAsync('asyncFail').catch(e => {
console.log("Got error", e)
});
}) This also takes care of rejected promises. |
Is there some limitations/caveats for child.call returned value as promise, like it's done at child.get functionality? Because if I need to pass some arguments to child model functions, then I need to switch from promise based code to event driven style.. but I wanna use just one of it
The text was updated successfully, but these errors were encountered: