(<any>window).SomeLibrary.SomeMethod(arg1,arg2)? - javascript

What is (<any>window) when used in Angular2?
I found it while researching the Stripe payment library:
(<any>window).Stripe.card.createToken({
number: this.cardNumber,
exp_month: this.expiryMonth,
exp_year: this.expiryYear,
cvc: this.cvc
}, (status: number, response: any) => {
if (status === 200) {
this.message = `Success! Card token ${response.card.id}.`;
} else {
this.message = response.error.message;
}
});
http://blog.mgechev.com/2016/07/05/using-stripe-payment-with-angular-2/
Looks like it's something that lets you use global objects inside a controller, but I don't really understand the details. Can't seem to find other answers on this.

Sometimes you’ll end up in a situation where you’ll know more about a
value than TypeScript does. Usually this will happen when you know the
type of some entity could be more specific than its current type.
Type assertions are a way to tell the compiler “trust me, I know what I’m
doing.”
It might be in two forms:
(<any>window)
or
(window as any)
See also https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions
Another way to do the same thing is using Square bracket syntax
window['Stripe'].card...
In this case typescript compiler will work as well

<any> indicates a cast in TypeScript, so converting window to an any indicates that you are no longer bound by the compiler to what it thinks the window object is and what properties it has.
(<any>window) is preventing compile time type error checking from flagging the call as invalid.

Related

Getting warning from VSCode when using CharAt with Vuejs

While trying to pick out the first character of a computed property I used charAt() function on it, but I am getting a little warning from VSCode that it is a wrong usage, although it is working.
computed: {
...mapGetters({
firstname: 'user/firstname',
lastname: 'user/lastname',
}),
initials () {
return (this.firstname.charAt(0).toUpperCase() + this.lastname.charAt(0).toUpperCase());
}
},
Property 'charAt' does not exist on type 'Computed'.Vetur(2339) - This is the warning I get. Could not find much on this over the web
This is a warning caused by vetur.validation.interpolation which validate interpolations in region using TypeScript language service.
Setting vetur.experimental.templateInterpolationService: false in your settings.json file will solved this issue for you.

Disable duplicate declaration validation in Acorn

I'm using Acorn to parse some syntactically valid JavaScript code into an ESTree for further processing. It appears that Acorn does some semantic checks too - in particular it throws an error for duplicate declarations. For example, parsing the following code throws an error of Identifier 'f' has already been declared:
function f() { return 1; }
function f() { return 2; }
I do not want such semantic errors to be checked - I'm doing custom processing on the resultant ESTree, so the semantic validity of the source code does not matter to me.
I've looked though the Acorn options for the parse(input, options) function, but I could not find anything that sounds like what I want.
Is there a way to disable such semantic checking?
It seems like there is no proper way to disable semantic validation. I managed to get what I want with an ugly hack, by overriding the raiseRecoverable method.
This worked for me (note that I'm using TypeScript here, but it would of course be possible to do the same in plain JavaScript):
import { Parser } from "acorn";
class SyntacticParser extends Parser {
raiseRecoverable(pos: any, message: string) {
if (message.includes("Identifier ") && message.includes(" has already been declared")) return;
(Parser.prototype as any).raiseRecoverable.call(this, pos, message); // weird call syntax required because the TypeScript types for Parser doesn't contain the `raiseRecoverable` method
}
}
It's an ugly hack because I'm filtering out the duplicate declaration message based on the stringified error message. However, there does not appear to be a better way.

Intercepting and interracting with a custom Error object in javascript

I am using a custom javascript modulue which has it's own Error objects. I would like to intercept those custom Error objects and take the appropriate path in my try{} catch{} block, distinguishing them from Javascript's built in Error objects such as ReferenceError, TypeError etc.
So a bit like this.
try {
// Some code that might produce a traditional javascript error
// or one of the errors raised by the module I am using.
}catch (error){
if(error instanceof ExchangeError){
// Handle this in a way.
}else{
// Probably one of the built in Javascript errors,
// So do this other thing.
}
}
So, in the example above, ExchangeError is a custom error belonging to that specific module, however, I am not able to run the instanceof on my error, despite the fact that when I do error.constructor.name I get ExchangeError.
My javascript scope simply does not know about that ExchangeError. So the question is, how can I intercept those kind of Error objects? I'm sure I can do it with string matching, but just wanted to check if there is a more elegant way.
One thing I tried, I have my own errors module, that has some custom errors in there, I tried to mimic the module's Error object:
class ExchangeError extends Error {
constructor (message) {
super (message);
this.constructor = ExchangeError;
this.__proto__ = ExchangeError.prototype;
this.message = message;
}
}
and import that through my errors module, but that did not work obviously.
By actually implementing my own ExchangeError I actually was doing something really really bad, I was blinding the instanceof check with my own ExchangeError, whereas the ExchangeError instance that was coming from the module, was NOT an instance of my own ExchangeError. That is why my if check was falling silent.
The solution is simply doing this:
const { ExchangeError } = require ('ccxt/js/base/errors');
Importing the error from within the module. Now the instanceof look up is working. I did not know that one can import bits and pieces from a module like that.
Thanks to #FrankerZ for pointing that out.

Is there a way to override the default JS error messages?

I'm guessing the answer to my question is no, but since I don't know enough about how Error.prototype works I figured it was worth asking: is there any way to change the error messages from the errors in Javascript?
For instance, if I get an error:
TypeError: (intermediate value) is not iterable
is there any way to change things such that I instead get:
TypeError: You expected an array but it wasn't an array dummy!
I thought about using a global error handler and then rethrowing them, but that would only work for uncaught errors. Is there any Error.prototype method I can change (or any other way) to do this?
Not at all important, just curious.
EDIT: Just to clarify two points:
1) I understand how try/catch works, but what I'm asking about is whether there is a way to control the messages generated before the error is thrown/caught (presumably by overwriting a method of Error.prototype).
2) An answer of "no there is no way to do this, all generating of JS error messages is handled internally and the JS code has no way to control it" would be perfectly legitimate (... if that's the case).
You have to override the TypeError class, not one of these methods.
const overridableMessages = [{
search: 'TypeError: (intermediate value) is not iterable',
replace: 'TypeError: You expected an array but it wasn\'t an array dummy!'
}]
class TypeError extends window.TypeError {
constructor (message) {
super(message)
overridableMessages.forEach((overridableMessage) => {
if (this.message === overridableMessage.search) {
this.message = overridableMessage.replace
}
})
}
}
window.TypeError = TypeError
window.onerror = function(msg, url, linenumber) {alert('Error : '+msg+'\nURL: '+url+'\nLine Number: '+linenumber);return true;}
// general error handler
Also:
try {
}
catch(err) {
alert(err); // here put your case with your messages.
}
// routine error handler
HIH,
I hate to answer my own question, but I found this line on the MDN which seems to pretty clearly answer things:
The global Error object contains no methods of its own, however, it does inherit some methods through the prototype chain.
Since the only methods it gets through the prototype chain are toString and toSource (neither of which controls an error's generated message), it appears (unless I'm missing some other mechanism that isn't Error.prototype-related) that there is no way to accomplish what I asked.

how to work with react-native's PushNotificationIOS.getInitialNotification

I'm trying to detect whether my react-native app was launched by the user tapping a push-notification banner (see this excellent SO answer on the topic).
I've implemented the pattern Mark describes, and have discovered that the "notification" objects being provided by PushNotificationIOS.getInitialNotification are really bizarre, at least in cases when there isn't a notification to retrieve. Detecting this case has been a PITA, and I'm actually quite confused.
From what I can tell, PushNotificationIOS.getInitialNotification returns a promise; this promise is supposed to resolve with either null or an actual notification object -- null when there is no notification waiting for the user. This is the scenario I'm trying to detect and support.
Here's why it's such a pain to detect; the following tests were all run when there is no notification to find:
// tell me about the object
JSON.stringify(notification);
//=> {}
// what keys does it have?
Object.keys(notification);
//=> [ '_data', '_badgeCount', '_sound', '_alert' ]
So it stringifies to empty, but it has four keys? K...
// tell me about the data, then
JSON.stringify(notification._data);
//=> undefined
// wtf?
These bizarre facts frustrate both my understanding and my ability to distinguish between cases where there's an actual notification to react to vs. cases where the mailbox is empty. Based on these facts, I assumed I could test for the members I want, but even the most careful probing produces false positives 100% of the time:
PushNotificationIOS.getInitialNotification()
.then((notification) => {
// usually there is no notification; don't act in those scenarios
if(!notification || notification === null || !notification.hasOwnProperty('_data')) {
return;
}
// is a real notification; grab the data and act.
let payload = notification._data.appName; // TODO: use correct accessor method, probably note.data() -- which doesn't exist
Store.dispatch(Actions.receivePushNotification(payload, true /* true = app was awaked by note */))
});
Every time I run this code, it fails to trigger the escape hatch and throws on let payload because undefined is not an object (evaluating 'notification._data.appName').
Can someone explain what's going on here? Is PushNotificationIOS.getInitialNotification broken or deprecated? How in JS is it possible to have a key that evaluates to undefined? How can I detect this scenario?
Experienced javascripter, pretty puzzled here. Thanks for any help.
BTW: using react-native v0.29.0
The notification is an instance of PushNotification, not a plain object, that's why it stringifies to an empty object since no custom toString was implemented for it.
It sounds like a bug to me (which should be reported if not already) that the object is created when no notification is available.
Anyway, to workaround this issue, your check should actually be:
if(!notification || !notification.getData()) {
return;
}
Update: Issue has been fixed in 0.31 - see Github issue for more details.

Categories

Resources