How to handle native exception in react-native - javascript

I want to handle native exception in react-native application. I'm currently using the react-native-exception-handler module to do this. All things are working fine except callback. If you read about given module api you will find setNativeExceptionHandler() method having three parameters i.e., exceptionhandler, forceAppQuit and executeDefaultHandler.
Here is usage about the method:-
// ADVANCED use case:
const exceptionhandler = exceptionString => {
// this block not executing
};
setNativeExceptionHandler(
exceptionhandler,
false
);
Any help would be appreciated.

I think that the issue is that you are not using it in bundle mode.
From the docs:
NOTE: setNativeExceptionHandler only works in bundled mode - it will show the red screen when applied to dev mode.
So you should try to build app and then try it.
Also be aware that some actions are not allowed when native exception is happening for ex. you can't use alert
From docs:
NOTE: alert or showing any UI change via JS WILL NOT WORK in case of NATIVE ERRORS.

Related

Angular Universal and browser feature checks

When developing a web app with jQuery or normal JavaScript, it is commonplace to check for feature availability first. So for example, if I want to use the document.oncopy event, I should first have something like this to ensure my code doesn't break for lesser browsers:
if ("oncopy" in document) {
// Feature is available
}
I'm a bit puzzled about how this would work in Angular2. I could still use the same if I expect to only run in the browser, but I'm specifically told to leave the DOM alone if I want to use Angular Universal and depend on templates or the DomRenderer instead. This allows the page to be pre-rendered on the server and provides a truly impressive performance gain.
But suppose I want a specific div to be invisible if the document.oncopy is unavailable. My understanding is that this is not recommended:
<div *ngIf="hasFeature()">...</div>
and
hasFeature() {
return 'oncopy' in document;
}
because then I'm still manipulating the DOM. Note that my example is about the document.oncopy but I could choose any feature whatsoever that doesn't have universal support.
I tested this using Chris Nwamba's tutorial on Scotch and added the following to the end of his Home template:
<div *ngIf="hasFeature()">Feature is supported</div>
<div *ngIf="!hasFeature()">Feature is NOT supported</div>
Update: Interestingly, it gave different results on different browsers. On Chrome 55, it executed as it would normally and showed the "Feature is supported" message. On IE11, I received the "not supported" message. In both instances the server log shows a EXCEPTION: document is not defined message, but the page still seems perfectly okay.
So what is the correct way to check for browser features if I want to use Angular Universal?
Update:
I also toyed around with using a field in the template and assigning that field from one of the life cycle hooks. ngAfterContentInit seemed like a fine candidate, but also causes an error on the server. It still runs fine in the browser with no weird effects (that I have noticed so far).
There are two ways to approach this:
Do the check only once the server is done rendering and the client is completely initialised (including the replay of user events done by preboot.js).
Return a reasonable default when the page is running on the server and perform the actual check only in the browser.
I started looking at the first option, but none of the Angular2 life cycle events will help with this. In fact, you can clearly see them all executing on the server and only then on the client.
I then started looking for something usable in preboot.js but quickly realised it was more complex than it needed to be.
So onto option 2 I went. It turns out checking for the browser is as easy as importing and checking isBrowser.
import { isBrowser } from "angular2-universal";
#Component({
// All the usual stuff
})
export class MyComponent {
// ...
hasFeature(): boolean {
return isBrowser && 'oncopy' in document;
}
// ...
}
And then use the template as I showed in the question.
To check if you're running on the server, import and use isNode in exactly the same way. There doesn't seem to be an obvious way to distinguish between Node and ASP.NET Core, but perhaps it's best not to write too much code that specific to platform.

Babel to translate JSX to JS

In C#, I get as an input a JSX file and want to translate it to JS. I want to use the babel library, and used this guide:https://babeljs.io/docs/setup/#installation
However, I am getting an exception of type:
An unhandled exception of type
'React.TinyIoC.TinyIoCResolutionException' occurred in React.Core.dll
Additional information: Unable to resolve type: React.IReactEnvironment
for this line: ReactEnvironment.Current
I have tried to create a new ASP.NET project, and no exception was thrown and everything worked just fine.
My question is: How can I still use babel in non web project?
You need to run an extra initialization step for non Web applications.
This initialization step is automatically done in Web applications.
If its a console application then use this function,
private static void Initialize()
{
Initializer.Initialize(registration => registration.AsSingleton());
var container = React.AssemblyRegistration.Container;
// Register some components that are normally provided by the integration library
// (eg. React.AspNet or React.Web.Mvc6)
container.Register<ICache, NullCache>();
container.Register<IFileSystem, SimpleFileSystem>();
}
And call it in the main method.
Take a look at the github console sample app for React.Net
Link for reference

Foundation Sites (6) javascript order

I am utterly confused as how to insert individual foundation javascript. it always seem to break my code. for example I need to use the dropdown menu js. in the documentation it state
Initializing
The file foundation.dropdownMenu.js must be included in your JavaScript to use this plugin,
along with foundation.core.js.
This plugin also requires these utility libraries:
foundation.util.keyboard.js
foundation.util.box.js
foundation.util.nest.js
this seem simple enough so I did the following in this order
bower_components/foundation-sites/js/foundation.core.js //check
bower_components/foundation-sites/js/foundation.util.mediaQuery.js
bower_components/foundation-sites/js/foundation.util.timerAndImageLoader.js
bower_components/foundation-sites/js/foundation.util.keyboard.js //check
bower_components/foundation-sites/js/foundation.util.box.js //check
bower_components/foundation-sites/js/foundation.util.nest.js //check
bower_components/foundation-sites/js/foundation.dropdown.js
bower_components/foundation-sites/js/foundation.dropdownMenu.js //check
bower_components/foundation-sites/js/foundation.equalizer.js
I follow what logical for me core 1st than util than plugin
yet it told me foundation.util.nest.js:6 Uncaught SyntaxError: Unexpected token =
if I put all foundation.min.js file the error go away, so I know it must be a dependency is missing or the order is not correct
is there any resource out there that is clear on the dependency of foundation js? instead everytime I have to trail and error it.
I'm having the same issue on my end. I am using Foundation as a GIT subtree in my project and actually have used this on a site I made just last week.
It seems that the problem is a newer version of function parameter declarations. In the code I had working, v6.1.2, the code in foundation.util.nest.js is:
Foundation.Nest = {
Feather: function(menu, type){
menu.attr('role', 'menubar');
type = type || 'zf';
versus the code in the newest version 6.2.0 which is:
const Nest = {
Feather(menu, type = 'zf') {
menu.attr('role', 'menubar');
It's that default/fallback declaration of "type" that seems to ruin everything. I look forward to a fix myself.
According to this link, my current version of Chrome (48) doesn't yet support default function parameters.
As of Foundation v6.2.0 the JavaScript codebase has been updated to ES6.
https://github.com/zurb/foundation-sites/releases
You'll need to add Babel to your build process to compile the ES6 code.
They have supplied a tutorial for this here:
https://github.com/zurb/foundation-sites/wiki/Upgrading-to-Foundation-6.2
Hope this helps.

Cordova: how to check if plugin is available at runtime?

How can the JavaScript part of a Cordova based application check if a certain plugin is available in the native part?
I tried to use cordova.require( 'cordova/plugin_list' ).metadata but it returns a list of the JavaScripts that have been loaded via cordova_plugins.js. Doing something like if ( typeof( window.plugins.MyPlugin ) != 'undefined' ) doesn't help either - while the JavaScript part of my plugin is loaded, the native part might not be available.
What I basically need is a way to react to these errors (copied from an iOS project)
ERROR: Plugin 'MyPlugin' not found, or is not a CDVPlugin. Check your plugin mapping in config.xml.
-[CDVCommandQueue executePending] [Line 158] FAILED pluginJSON = [
"MyPlugin1093761140",
"MyPlugin",
"someAction",
[]
]
that ocurr when I try to do
cordova.exec( successFn, errorFn, 'MyPlugin', 'someAction', [{}] );
and MyPlugin is not included in the native project.
You could make a plugin which retrieves the list of available plugins. Specifically, you could read the names of classes within the various <feature> tags in the config.xml which is packed within your project. On Android this can be found in the xml folder in the res folder where other resources are. Not sure about where it is on iOS at the moment.
Alternately, you could detect the error within the errorFnthat you had in your example, since it'll be a string that says "Class not found".
Either method is asynchronous however, so it won't be as nice as just checking globals.

Parse can't find localStorage variable in React Native

I have a React Native app that works fine with the Chrome debugger open. Once I disable it though, I keep getting the following error whenever I try to make any Parse calls:
The call stack leads back to the following code attempting to log a user in:
Parse.User.logIn(
email,
password,
{
success: function(res) {
console.log('success');
},
error: function(error) {
console.log(error.code + ' ' + error.message);
}
}
);
I've tried removing the console statements, in case the error had to do with the console not being available, but no avail. This happens with other Parse calls, and always has to do with the missing localStorage variable.
Thanks in advance for any help!
UPDATE:
Looks like there is a similar issue with Firebase. https://groups.google.com/forum/#!topic/firebase-talk/Y_usPRhOIYA
They mention that the problem has to do with there not being a polyfill for localStorage.
The answers above are technically right, but Parse has provided a solution that doesn't require a polyfil or downgrading. This was due to my perpetual lack of reading. I found this on the Parse React docs:
As of version 1.6, the Parse JS SDK has a different build for React
Native. If you're using Parse+React on React Native, you'll need to
require the 'parse-react/react-native' package instead.
For example:
// For React Native apps
var React = require('react-native');
var Parse = require('parse/react-native');
var ParseReact = require('parse-react/react-native');
Sorry for not mentioning I was using Parse React as well. I thought the problem was just with Parse, as I hadn't begun to add data subscriptions via Parse React.
That's correct (with polyfill). There is no localStorage added as polyfill nor the Apple's embedded javascriptCore engine has localStorage implemented (where Chrome's v8 has it implemented of course). Main reason is that localStorage is synchronous and React should only work with asynchronous operations by design.
There is a nice solution/mini-polyfill that replaces localstorage with an in-memory version: https://gist.github.com/juliocesar/926500 . That should let parse use localstorage for cache (that's the main purpose they are using it now I believe). The data will not be persistently stored between application executions. I am not sure if you can disable localstorage use by Parse, but that's another possibility to explore.
I downgraded to 1.5.0 and working now.
"dependencies": {
"parse": "1.5.0",
I do not think that even being forced to use Parse+React is a good enough solution. For example I am building my app with Redux, it makes a lot more sense for me to keep all of my API Requests inside my action creators.
In 1.6.0 Parse is forcing us to use Local Storage, when React Native does not support it. React Native does however support AsyncStorage.
For me I just downgraded to 1.5, hopefully they will give an option to use Local Storage or Async Storage in the future.
So people that stumble upon this and would not like to be forced to use Parse+React your answer is to downgrade to 1.5, in your package.json change your dependencies to "parse": "1.5.0".
This problem can easily be fixed by:
npm install localstorage-polyfill
and then in App.js
import 'localstorage-polyfill';
EDIT: this error potentially means you have outdated or incompatible library dependencies. You can try to reinstall with rm -rf node_modules; npm install

Categories

Resources