title | position | guide | environment |
---|---|---|---|
Chapter 5—Plugins and npm Modules |
6 |
true |
angular |
As you build more complex apps, you'll likely run into functionality that is not implemented in the NativeScript modules. But no worries, as NativeScript lets you leverage npm (node package manager) to import npm modules into your apps. Alternately, you can install NativeScript plugins, which are simply npm modules that can access native code and use Android and iOS SDKs, if required.
In this chapter, you'll install and use an external email validator module to verify the format of email addresses as they are entered on the registration screen. Then, you'll add a NativeScript plugin, NativeScript social share, to let users share their grocery lists using their device's native sharing widget.
It would be nice to be able to make sure people are entering well-formatted email addresses into your app on the registration screen. You could write this functionality yourself, but validating email addresses is surprisingly tricky, and it's a lot easier to use one of many npm modules that already provide this validation. For Groceries let's see how to add this email-validator module to test for valid addresses.
Return to your terminal and make sure that you are working in the root directory in your Groceries project folder, a.k.a. here:
Groceries <----------------
├── app
│ └── ...
├── package.json
└── platforms
├── android
└── ios
From the root directory install the email-validator module:
npm install email-validator --save
The install process does a few things in the background. First, because you added the --save
flag, npm records this dependency in your app's package.json
. If you open your package.json
you should see "email-validator"
in your app's "dependencies"
array.
"dependencies": {
"email-validator": "^1.0.4"
}
The npm CLI also creates a node_modules
folder in the root of your app. This folder contains the code for the email-validator module, which is a bit of validation logic in node_modules/email_validator/index.js
.
TIP: By saving your app's npm dependencies in your
package.json
file, you can always regenerate yournode_modules
folder by runningnpm install
. Because of this, it's a common practice to exclude thenode_modules
folder from source control. The Groceries app uses git for source control, and as such includesnode_modules/
in its.gitignore
.
Now that you have the module installed let's look at how to use it.
Open /app/shared/user/user.ts
and replace the existing contents of the file with the code below:
var validator = require("email-validator");
export class User {
email: string;
password: string;
isValidEmail() {
return validator.validate(this.email);
}
}
NOTE: The NativeScript framework's
require()
method is configured to look at the"main"
value in an npm module'spackage.json
file. In the case of this module, the"main"
value is"index.js"
. Therefore, when you runrequire("email-validator")
, you're actually requiring the file atnode_modules/email_validator/index.js
. You could also typerequire("email-validator/index")
to retrieve the same file.
To make use of this validator, open app/pages/login/login.component.ts
and paste the following code at the beginning of the existing submit()
function:
if (!this.user.isValidEmail()) {
alert("Enter a valid email address.");
return;
}
Now, if the user attempts to login or register with an invalid email address, they’ll see an alert that points out the error. However in order to test out this change you’ll need to do one more thing.
As we mentioned in chapter 1, although the tns run
command is smart enough to reload your app for most changes you make to your app, certain changes require a full build—most notably, changes to native files in app/App_Resources
, new modules installed with npm install
, and new NativeScript plugins.
For NativeScript to recognize this new email-validator npm module, type Ctrl+C
in your terminal to kill the existing tns run
watcher if it’s still running, and then use tns run
to rebuild your application and deploy it to an emulator or device.
tns run ios
Or
tns run android
After your app launches again, if you type an invalid email address and attempt to login, you should see an alert that prevents the submission:
In general npm modules greatly expand the number of things you're able to do in your NativeScript apps. Need date and time formatting? Use moment. Need utility functions for objects and arrays? Use lodash or underscore. This code reuse benefit gets even more powerful when you bring NativeScript plugins into the picture.
WARNING: Not all npm modules work in NativeScript apps. Specifically, modules that depend on Node.js or browser APIs will not work, as those APIs do not exist in NativeScript. The NativeScript wiki contains a list of some of the more popular npm modules that have been verified to work in NativeScript apps.
NativeScript plugins are npm modules that have the added ability to run native code and use iOS and Android frameworks. Because NativeScript plugins are just npm modules, a lot of the techniques you learned in the previous section still apply. The one big difference is in the command you use to install plugins. Let's look at how it works by installing the NativeScript social share plugin.
Return to your terminal, make sure you're still in the root of your app, and run the following command:
tns plugin add nativescript-social-share
The install process does the same thing that the npm install
command does—including retrieving the module from npm, installing the module in node_modules
, and saving the module as a dependency in your app's package.json
—but the tns plugin add
command additionally configures any native code that the plugin needs to use.
For example the NativeScript push plugin uses both iOS and Android SDKs, and the tns plugin add
command takes care of installing those. The NativeScript flashlight plugin needs permissions to use the camera on Android, and the tns plugin add
command takes care of setting that up too.
Now that you've installed the social share plugin, let's look at how to use it.
Open app/pages/list/list.component.ts
and add the following line at the top of the file, which imports the social share module you just installed:
import * as SocialShare from "nativescript-social-share";
Next you have to build some UI that lets you share a grocery list. To do so, open app/pages/list/list.html
and add the following code at the very top of the file:
<ActionBar title="Groceries">
<ActionItem text="Share" (tap)="share()" android.systemIcon="ic_menu_share_holo_dark" ios.systemIcon="9" ios.position="right"></ActionItem>
</ActionBar>
This code defines an ActionBar, which is a UI component that appears on the top of the screen, and which can optionally include menu items, or <ActionItem>
components.
NOTE: On iOS devices,
<ActionItem>
s are placed from left to right in sequence; you can override that (as the code above does) by providing anios.position
attribute.
Next, to add a bit of styling to this new <ActionBar>
, add the following CSS to the top of your app/app.css
file:
ActionBar {
background-color: black;
color: white;
}
Finally, now that you’ve installed and imported the plugin, and setup a UI to use it, your last step is implementing the <ActionItem>
's tap
handler. Open app/pages/list/list.component.ts
again and add the following function to the ListComponent
class:
share() {
let listString = this.groceryList
.map(grocery => grocery.name)
.join(", ")
.trim();
SocialShare.shareText(listString);
}
This code takes the grocery data from the grocery list array, converts the data into a comma-separated string, and passes that string to the social share plugin’s shareText()
method.
WARNING: Because this section had you install a NativeScript plugin, you’ll have to rebuild your app one last time in order to test your changes. If you don’t remember how refer back to the previous section for instructions.
After you run the app, you'll see a new button at the top of the screen. When you tap it, the native iOS or Android sharing widget will show to let you post your groceries to your social networks, or send them via email, message, or any other method you prefer.
Pretty cool, huh? The ability to use npm modules greatly expands the number of things you're able to do in a NativeScript app. Need to compose emails in your app? Try out the NativeScript email plugin. Need to use the clipboard in your app? Try out the NativeScript clipboard plugin.
If you're looking for NativeScript plugins start by searching both the Telerik NativeScript Plugins Marketplace and our community-curated list of plugins on npm. If you don't find the plugin you need, you can request the plugin on our ideas portal, or you can take a stab at creating the plugin yourself.
Between NativeScript modules, npm modules, and NativeScript plugins, the NativeScript framework provides a lot of functionality you can use to build your next app. However, we've yet to talk about NativeScript's most powerful feature: the ability to directly access iOS and Android APIs in TypeScript. Let's look at how it works.