Passing Complex Data Through The Angular 2 Router With NativeScript

I recently wrote a tutorial for navigating a NativeScript Angular 2 application using the Angular 2 Router.  In this tutorial I demonstrated how to create a multiple page application, navigate between pages, and even pass simple string parameters between the pages during navigation.  However, what happens when the data you need to pass isn’t so simple?

We’re going to take a look at some of the ways to pass data between routes in a NativeScript application that makes use of Angular 2.

Before getting too far ahead of ourselves, I recommend revisiting the article I wrote regarding navigation as this will be more or less a continuation of that article.

There are many ways to accomplish the task of passing around data in an Angular 2 application.  We’re going to look at two of those possibilities.

Using Query Parameters

The first, and probably the quickest, way to pass data around would be to use query parameters.  Now this isn’t the same as the URL parameters that we saw previously.

Let me explain.

If viewing the URL within a web application, you’d notice that URL parameters look something along the lines of /people/:id where :id could be any value in the path.  You can have as many of those parameters as you want, but the more you have, the messier they become.

Query parameters look more along the lines of /people?id= where id can equal anything and you can have as many parameters as you want.  The query parameters would be separated by the ampersand character.

So where am I going with this and how does it relate to Angular 2 or NativeScript?

When working with query parameters, you don’t need to define them in your routes file, and they can be named parameters.  For example, take the following TypeScript code:

The Angular 2 navigate method, found in the Router component, accepts an optional NavigationExtras object.  This object has a property called queryParams where you can pass any object you want.

There is a catch however.  The queryParams object must be flat.  This means no nested objects or arrays can be present.  Remember though, this could be a step up from the plain strings we were using with the URL parameters.

In the receiving page, you would receive these query parameters like the following:

Receiving query parameters is really no different than receiving URL parameters.

So what if you want to pass around more complex parameters than just flat objects or strings?  Well you could serialize objects into strings and pass them around like this:

On the receiving end, you’d receive address as a string which can be parsed back into an object.

However, there are much better ways to accept complex data without bothering with object serialization and parsing.

Using Application Providers

While this next method isn’t technically related to the Angular 2 Router, it is a method for passing around data nonetheless.  A perfectly acceptable way to pass around data would be to use an application provider that is shared with all pages of your application.

Take the following provider:

This provider has a public variable called storage that can be used on any page we inject it into.  This variable will be of the same instance on every page.

With that said, let’s revisit the first page:

Notice how we’re injecting that Data provider into our page and setting it to an object before we plan to navigate?  On the receiving page we can do something like this:

Notice we’ve injected the Data provider again, but instead of setting it, we’re reading from it.

Just to clear up any loose ends, bootstrapping the Data provider in the application’s @NgModule would look like the following:

Notice how we’ve included providers in the above code.

Conclusion

You just saw two alternatives to passing around URL parameters found in the previous article I wrote on the topic of navigation in an Angular 2 NativeScript application.  While query parameters and providers are not the only ways to accomplish the job, they are probably the easiest in my opinion.

The Angular 2 documentation references Router data and resolves, but those can probably be avoided in many scenarios.  At the end of the day, you may just want to re-evaluate your data needs.

A video version of this article can be seen below.

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

  • uruorlando

    Hi Nick, great tutorial as usual…
    If using application providers, would it be possible to add the onTap function to the provider as to avoid repeating this function on every component that needs to pass data and navigate to a different component???
    maybe adding parameters to the function call onTap( pageToGo, DataToSend) to indicate to what component we want to navigate to (function parameter “pageToGo) and what data we are sending (function parameter “DataToSend)???

    Thanks

    • I believe it would be possible if you inject the provider as public so it can be accessed via the UI.

    • I believe it would be possible if you inject the provider as public so it can be accessed via the UI?

  • Ibrahim Eim

    Greetings Nick, it’s good tutorial
    How can I remove a previous page from the history stack. like in your example if I want to close the application on page2 when someone presses the back button

  • Holly Pepper

    Hi, I would like to use the second approach above: Using Application Providers

    I have followed the approach, but when I console.log the data on “page2” it comes back us undefined.

    Is anyone else having this problem?

    • Holly Pepper

      Nevermind – I have just seen ‘Nativescript’