In my Node.js application I'm trying to use apply to make a function call in the Stripe library since the access token parameter is optional. However, I'm getting a type error.
var args = [data];
if(accessToken) {
args.push(accessToken);
}
args.push(function(err, customer) {
...
});
stripe.customers.create.apply(this, args);
Uncaught TypeError: Cannot call method 'createUrlData' of undefined
at /home/codio/workspace/node_modules/stripe/lib/StripeMethod.js:33:24
I believe this a result of using strict mode but let me know if this is expected behavior. I'm using version 2.8.0 of the Stripe Node.js library.
Likely your this is undefined, and apply sets the context (what this is) in the called function. Under normal circumstances, the called function's this would be stripe.customers, so try:
stripe.customers.create.apply(stripe.customers, args);
Related
I'm using 'soft-assert' library (soft-assert library) to apply assertion on my test steps without stopping the test if any of them fail.
According to the documentation, all soft-assert is verified at the end of the test by using softAssertAll() command. And this works very well. However, if nothing fails, I don't see any explicit message in my test result as when I use expect command.
So, I'm trying to apply expect over the softAssertAll() command, as it's seen below, but I'm getting the error message:
"expected { Object (userInvocationStack, specWindow, ...) } to be a function"
What I'm trying to do:
expect(cy.softAssertAll()).not.throw(Error)
Does anyone know how can I do this or solve the error in the image below?
Thanks in advance.
See the Chai example for throw
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw();
Note you pass in the function name without invoking it. I think this allows chai to wrap the function invocation in a try-catch and gracefully report the failure.
You can't do the same with a Cypress custom command as it will not raise errors in the same way as badFn above. Internally it swallows any error and sets the state of the test to "failed".
You could reasonably expect this to work
expect(jsonAssertion.softAssertAll).not.throw()
however there's an internal error in jsonAssertion that seems to be related to the this reference inside it's class.
TypeError: Cannot read properties of undefined (reading '_softThrowJsonDiffArray')
To fix, use an arrow function
const testSoftAssertAll = () => jsonAssertion.softAssertAll();
expect(testSoftAssertAll).not.throw()
or shorter
expect(() => jsonAssertion.softAssertAll()).not.throw()
Check the diff array
This is cleaner and clearer
// expect all soft-assert to be passing
expect(jsonAssertion.jsonDiffArray).to.eq(undefined)
// expect first soft-assert to fail with a certain message
expect(jsonAssertion.jsonDiffArray[0].error.message).to.contain('Illegal salmon')
I have this code in my middleware:
const UserMiddleware = {
isNumber(n) { return !Number.isNaN(parseFloat(n)) && !Number.isNaN(n - 0); },
// eslint-disable-next-line consistent-return
validateSignUp(req, res, next) {
const allSignUpErrors = [];
console.log(this.isNumber(5));
if (this.isNumber(req.body.first_name)) {
allSignUpErrors.push('First name must be a text value');
}
if (allSignUpErrors.length !== 0) {
return res.status(400).json({
status: 400,
error: allSignUpErrors,
});
}
next();
},
I normally use 'this.' to call functions and variables in objects without problems. I suspect that the 'next()' function in the middleware is what is causing me to get the error below at the point of using 'this.' to call a function.
TypeError: Cannot read property 'isNumber' of undefined
I have tried using 'bind' to call the function but the 'undefined' error still occurs.
Is the 'next()' function the one breaking the normal functionality? Is there a way to correctly use 'this.' to call functions in middleware?
Change:
this.isNumber(...)
to:
UserMiddleware.isNumber(...)
The value of this inside a middleware function will not be your UserMiddleware object unless you specifically used .bind() or some similar technology when passing it as middleware.
For help with further options, show us the code where you're using validateSignUp().
For example, if you were doing:
app.use(UserMiddleware.validateSignUp);
Then, you could set the desired value for this by using .bind() like this:
app.use(UserMiddleware.validateSignUp.bind(userMiddleware));
Passing UserMiddleware.validateSignUp to a function immediately loses the association with the UserMiddleware object and the this value when that function gets called will be determined by how the caller calls the function and won't be the UserMiddleware object. Using .bind(UserMiddleware) forces the desired this value to be set. .bind() actually creates a wrapper function who's sole job is to reattach the desired this value and that wrapper function is what is passed as the middleware handler. The middleware infrastructure calls the wrapper function with the wrong this value and then the wrapper function calls your validateSignUp function with the desired value of this - probably using .apply().
For a look at how .bind() works, you can see a polyfill for it here on MDN. For more of a discussion of how the value of this is set, see Six ways of setting this.
According to https://dev.outlook.com/reference/add-ins/Body.html:
The GetAsync() method takes in 3 parameters. The first one is the Coercion Type which according to their documentation is a string value. The other two parameters for GetAsync are options and callback which are optional.
My code: var body = item.body.getAsync("html");
which gives this exception:
Exception details: outlook-web-16.00.js:formatted:5873 Uncaught Error: Sys.ArgumentTypeException: Object cannot be converted to the required type.
Am I not using the getAsync() method correctly? Most of the example code I've found online are using the callback parameter as well but if the options and callback parameters are optional and I only really need to get the contents of the email body as html, shouldn't this work?
P.S. This isn't an API versioning issue. I am definitely on 1.3 and body.getAsync does not return undefined.
Am I not using the getAsync() method correctly? Most of the example code I've found online are using the callback parameter as well but if the options and callback parameters are optional and I only really need to get the contents of the email body as html, shouldn't this work?
Since this method is a asynchronous, to get the result we have to use the callback. This sample should work:
Office.context.mailbox.item.body.getAsync("html", processHtmlBody);
function processHtmlBody(asyncResult) {
console.log(asyncResult.value)
}
This is a thread discussing getting the return value from asynchronous function using JavaScript.
Consider this (simplified) extract from a class:
function PluginsEngine() {
this.allPluggins = require('./plugins');
};
PluginsEngine.prototype.applyPlugins = function(incomingData, done){
// bind the incoming data to each plugin
var key;
for (key in this.allPluggins)
this.allPluggins[key] = this.allPluggins[key].bind(undefined, incomingData);
async.parallel(this.allPluggins, done);
};
The constructor loads a set of anonymous functions and the "applyPlugins" method then passes the "incomingData" (string) to each and these are executed using async.
When writing tests against this I am seeing a strange behavior in that calling "applyPlugins" runs fine, but calling it again immediately afterwards causes the error:
TypeError: string is not a function
Adding some additional debug, I can see that allPluggins is empty (functions not available) when run the second time.
Can anyone advise why the variable is losing the functions?
File: MainApp.js
var reqHandler = reqire('HTTPRequestPostHandler')..
...
...
var httpRequestHandler = new reqHandler();
app.post('/', httpRequestHandler.handleRootPost);
File: HTTPRequestPostHandler.js
HTTPRequestPostHandler =function(){
this.someVar = value;
}
HTTPRequestPostHandler.prototype.handleRootPost{
console.log(this.someVar) //Error -> this.someVar is undefined.
}
I have these 2 files. The MainApp.js is where express is configured and various handlers for each endpoints e.g. '/'.
But when a post request occurs and the request handler (HTTPRequestPostHandler.prototype.handleRootPost) is invoked, I get a undefined error while accessing the variable this.someVar.
Why is this happening. What am I doing wrong here.
It's not a scope issue, it's a this issue.
Normally in JavaScript, this is set entirely by how a function is called, not where it's defined. So what's happening is you're passing your method in as a callback, but since it's not being called in a way that sets this to be your instance. (The next version of the specification, ES6, will have "arrow functions" that have this bound to them rather than being set by how they're called.)
The usual way that this gets set during a function call is when you call the function as part of an expression retrieving the function reference from an object, e.g.
foo.bar();
That calls bar with this set to foo. But this:
var f = foo.bar;
f();
...does not. this will be undefined (in strict mode) or the global object (in loose mode).
Other ways to set this are via Function#call and Function#apply, which let you call the function and explicitly say what this should be.
You can solve this with bind:
app.post('/', httpRequestHandler.handleRootPost.bind(httpRequestHandler));
bind returns a function that, when called, will call the original function with this set to what you pass in as the first argument.
More (on my blog):
Mythical methods
You must remember this