Cannot use Android classes in NativeScript 2 - javascript

I am using NativeScript 2.0 with Visual Studio Code and TypeScript 1.8 support (Windows).
I am developing a module, lets say MyModule-common.ts with an Android specific implementation (MyModule.android.ts).
Currently I cannot access Android classes!
If I write something like
var MyModule = require("./MyModule-common");
export class MyClass {
private _activity: android.app.Activity;
}
I get
error TS2503: Cannot find namespace 'android'
when I build my project.
Is there something to install extra or configure?

The TypeScript definition files for Android are by default not included as they are fairly large.
You can get then by doing a npm install tns-platform-declarations --save-dev

Related

Unexpected identifier {classname} when I try to import a class

I get an "Unexpected identifier" error when I try to import a class.
I'm importing class this way:
Class to be exported (WindowManager)
export default class WindowManager {
sayHello() {
console.log('hello')
}
}
Class which imports (Main)
import WindowManager from './handlers/WindowManager';
WindowManager = new WindowManager();
WindowManager.sayHello()
Folder hierarchy
Class which imports (Main) > handlers > Class to be imported (WindowManager)
Extra info
Throws the error at this line of code (Main)
import WindowManager from './handlers/WindowManager.js';
I've looked into Unexpected Identifier {classname} when importing JavaScript Class into another Class and make changes and still nothing
I was able to fix this by migrating to TypeScript.
What is TypeScript?
TypeScript is JavaScript on steroids, basically. It adds types, private methods, etc. Also provides a compiler which compiles your TypeScript code into JavaScript code! So you don't have to worry about compatibilty, you write on TypeScript and then compile to JavaScript with a simple command.
How to install TypeScript?
npm install -g typescript
How to use TypeScript?
Enter your project folder (where package.json is);
Generate tsconfig.json by running tsc --init;
Create your TypeScript index file;
Run tsc on terminal to compile ALL TypeScript project files to JavaScript;
Notice that your index TypeScript file was compiled to JavaScript;
Use the compiled JavaScript file as the main entry point on package.json;
Start your app/website/whatever heheh.
Notes:
Everytime you make changes to TypeScript file you have to use tsc
to recompile the code and make the changes on the JavaScript file;
VS Code comes with TypeScript support, if you're using Atom you can install TypeScript package by following this tutorial: Installing atom-typescript package.
Happy coding!
Articles that helped me:
VS Code Tutorial
TypeScript and Electron
How to auto-generate TypeScript config json?
Why TypeScript? - YouTube video

How to setup the react native navigation on android?

I have some issue with WIX react native navigation when I installed them,
I'm doing the steps in the documentation correctly but when running the app and Configure the libs and when up to Configure react native vector icon,
I have " Build Failed ".
> Configure project :react-native-vector-icons
The CompileOptions.bootClasspath property has been deprecated and is scheduled to be removed in Gradle 5.0. Please use the CompileOptions.bootstrapClasspath property instead.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex Unable to merge dex
so I don't Know what's wrong,
please if you have the same issue and fixed them, help me
For navigation between screens and Routing and navigation for your React Native apps you can switch to React Navigation 3x https://reactnavigation.org/. Its an extensible yet easy-to-use navigation solution written entirely in JavaScript (so you can read and understand all of the source), on top of powerful native primitives.
If you're already familiar with React Native then you'll be able to get moving with React Navigation quickly!
Install the react-navigation package in your React Native project.
yarn add react-navigation
or with npm
npm install --save react-navigation
Next, install react-native-gesture-handler. If you’re using Expo you don’t need to do anything here, it’s included in the SDK. Otherwise:
yarn add react-native-gesture-handler
or with npm
npm install --save react-native-gesture-handler
Link all native dependencies:
react-native link react-native-gesture-handler
No additional steps are required for iOS.
To finalise installation of react-native-gesture-handler for Android, be sure to make the necessary modifications to MainActivity.java:
package com.reactnavigation.example;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
#Override
protected String getMainComponentName() {
return "Example";
}
#Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
#Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
You're good to go!

Could not find a declaration file for module 'react-native-foo-package'

while I added any component to my pure react-native project, the application screen turns to the white empty page.
The import 'react-native-foo-package' line has '...' near the package name, and it has this message:
[ts]
not find a declaration file for module 'react-native-foo-package'. '/project/node_modules/'react-native-foo-package'/index.js' implicitly has an 'any' type.
Try npm install #types/'react-native-foo-package' if it exists or add a new declaration (.d.ts) file containing declare module 'react-native-foo-package';
npm install #types/'react-native-foo-package' couldn't help, because this package doesn't exist in npm.
I don't use any typescript file or related code to typescript.
react: "16.6.0-alpha.8af6728"
react-native: "0.57.4"
This question Could not find a declaration file for module 'module-name'. '/path/to/module-name.js' implicitly has an 'any' type doesn't answer my question, because, in my package.json file, there is no "main" exists.
Well #Samane Yaghoobi is right! it has nothing to do with "main":"index.js".
Here's what you should do. After successfully setting up the library in your project on whatever platform (VsCode or Atom). Re run the project from the command line => react-native run-android. After that, navigate to your project in Android Studio. Then open up build.gradle and sync your gradle again. Then just to make sure, checkout the MainApplication in Android Studio to see if the file(e.g. import com.whatever.foo) imported properly, if everything looks good, you are good to go. If you need further instructions in setting up the library in VsCode/Atom let me know, I will create visual presentation to make things much more clear.

Using TypeScript types from JS

I've enabled checkJS and allowJS in Typescript and created a simple fooInterface.d.ts file:
declare interface FooInterface {
x();
}
I'm trying to typecheck a JS file against this interface:
/**
* #implements {FooInterface}
*/
class Bar {
y() {}
}
However I can't get it to throw an error upon running tsc.
Also tried simply writing declare class, didn't work either.
How can I reuse types from .d.ts files in JSDoc+JS?
Supporting the JSDoc #implements tag has been requested in TypeScript and is tracked by https://github.com/Microsoft/TypeScript/issues/17498
The #extends tag will be supported in the next release of TypeScript (2.7) and is already available in the nightly builds (typescript#next) which, I might add, are remarkably stable.
You can get the nightly build with your package manager of choice. For example
using npm
$ npm install typescript#next
using jspm
$ jspm install typescript#next
using yarn
$ yarn add typescript#next

Which npm packages will and will not work on Angular 2? How do I tell?

Does an NPM package need to be modified to be compatible with Angular 2 (eg. add in typings, make directives for them) or will any existing package work? If they're not all compatible, how do I know what is and what is not compatible?
For example, say I want to import this package (https://github.com/pvorb/node-md5). I'm aware there is a ts-md5 package for angular 2 to do md5 - I'm just using this package as an example.
How would I get this to work?
I've installed it using
npm install md5 --save
npm install #types/md5 --save
but I can't seem to be import it
import {md5} from 'md5';
I get this error message after I try to run
Module
'"/Users/xxx/Source/tempProjects/ngUnderscore/node_modules/#types/md5/index"'
resolves to a non-module entity and cannot be imported using this
construct.
I'm not sure what this message means. Does it mean that in its current state, the package is not compatible or am I trying to use the package incorrectly?
I managed to make it work using declare and require instead of import (import won't work for this non-module lib)
declare const require: any;
const md5 = require('md5');
If you don't want to workaround import like this, you can try using Typescript MD5 implementation called ts-md5. Then import like the one below should work. (referenced from this question)
import { Md5 } from 'ts-md5/dist/md5'
If there is no TS implementation, you can search for the types in DefinitelyTyped and then simply install package by npm i --save-dev #types/{package-name}
If the library works on your project depends on many factors: your Angular version, your TypeScript version, etc.
This said, is obvious that we should check the library's documentation and see which dependencies has and its versions, and of course the library should be the Angular 2 version of itself. Following your example, there are several md5 libraries but if you use TypeScript you should maybe consider this one: https://www.npmjs.com/package/ts-md5
If we have all that covered but still there is something not working because of some type of incompatibility, like for example:
My version of angular is 2, the library I just installed works with Angular 4. I have code full of <template>, library uses <ng-template>... What can I do?
You can fork the library in github and modify whatever you need to asure it is compatible with your project. Steps:
Fork library repository and modify what you need
Subscribe to main library repository in order to be updated with changes
In packages.json use your forked version of the library, for example:
"ng2-datetime": "https://github.com/my_user/ng2-datetime/tarball/my_forked_version_name",
If you think that your modifications could suit other users... Make a Pull request! :D
This is more of a TypeScript question since md5 is not an Angular package.
The key is to get the import correct to be equivalent to a require() function.
import * as md5 from "md5";
Use directly in TypeScript file:
console.log(md5('message'));
To use this on the template, preferably it should be used in method implementation, but can also be exposed directly. Add it as a property on the Component:
md5: any = md5;
Then on the template:
{{md5('message')}}
They usually say which Angular it is meant for, sometimes you have one package for both or for each.
If you are using an Angular 1x package and there is no Angular2 compatibility, then you can just use ngUpgrade.
But If you are using a common plugin then there must be an angular 2 solution.
If you want the other way around then you're probably going the wrong way.
The issue you experienced is not related to Angular. It is an existing issue on TypeScript when importing CommonJS packages.
The rule of thumb (my recommendation) is to stay away from using the interop feature (i.e. import * as X from 'x') when importing CommonJS and use the "old" syntax instead (i.e. import X = require('x')).
When CommonJS is exporting a function in the form of module.exports = function() {...}, import * as X from 'x' does not work.
This includes the case when the package is exporting an ES6 class but transpiling to ES5 with Babel.
You may see some packages do work with this syntax, but that is because the typings have a hack in it:
declare module 'x' {
function foo(): void
namespace foo {} // <-- the hack
exports = foo
}
There are other reasons the interop is not a good idea, including the syntax between TypeScript (import * X from 'x') and Babel (import X from 'x') does not agree.
You can learn more about it here and follow the links:
https://github.com/unional/typescript-guidelines/blob/master/pages/default/modules.md#import-keyword
UPDATE: with TypeScript#2.7 released, you can now do import EditableElement from 'Transformer' directly.
Turn on esModuleInterop in your tsconfig.json

Categories