WordPress REST API – Part 4 – Ionic 3

Standard

Ionic 3 + Angular 4

This post follows on from posts about hybrid mobile app development using the new WordPress REST API and Ionic: Part 1, Part 2, Part 3

Part 3 contained a walk through of the Ionic 1 code. What follows is a walk through of the code for an Ionic 3 app.

From following the steps in part 2 By now you should have a [very basic] Ionic app running in your browser. The app will allow you to:

  • Authenticate with your remote, WordPress REST API enabled, website.
  • Make a post from the mobile app to your WordPress site.
Ionic 3 to WordPress

Ionic 3 to WordPress

Pretty simple stuff.

The code that performs the magic is pretty simple too.

Ionic Project Structure (Ionic 3)

Ionic 3 Project Structure

Ionic 3 Project Structure

As you can see from the folder structure below there are quite a few folders in our Ionic App.

However, the important files and folders are as follows:

  • src/app: The 1st component to be shown on screen for the app. Things like navigation routes are configured here.
  • src/pages: The pages for the app are in here i.e. the Login and Report pages.
  • src/providers: This folder contains reusable services to perform business logic e.g. authentication and connection to WordPress
  • ionic.config.json: This file contains configuration options for the app. In Part 2, we changed a setting in this file to point to our WordPress site.

The folder structure is much like any other Angular 4 application, so we will head straight to the code to see what the key lines are:

/app/app.component.ts

As this component is the entry component for this app we configure if the user should be navigated to the Login or Report screens on startup.

In this file we:

  • Start listening to our UserProvider (see user.provider.ts) to see if the logged in/out event is fired.
  • If the logged in event fires navigate to the Report page, otherwise go to the Login page.
constructor(
    private events: Events,
    private userData: UserProvider
  ) {
    // start listening to login and log out events
    this.listenToLoginEvents();
    // check to see if user has logged in before
    // if they have there will be a logged in event fired
    userData.checkedLoggedInStatus();
  }

  listenToLoginEvents() {
    // if the user is logged in then navigate to the Report page
    this.events.subscribe('user:login', () => this.rootPage = Report);
    this.events.subscribe('user:logout', () => this.rootPage = Login);
  }

/src/providers/user.provider.ts

In the previous step we saw that a UserProvider was referenced; this provider is declared in user.provider.ts.

The main job of the UserProvider is to check the username and password in order to receive an authentication token from the WordPress server. This job is outlined in the ‘login’ function.

The login function will:

  • Contact the WordPress server with the username and password to ask for an authentication token.
  • If successful the token will be used in every subsequent http call to the WordPress server. The way we do this is by creating our own http client and injecting the token in every header (see http-client.ts).
  • The authentication token will be stored in case the user comes back to the app at a later date.
  • An event is fired to tell subscribers that the user is now logged in.
// this is a unique token for storing auth tokens in your local storage
  // for later use
  AUTHTOKEN: string = "myauthtokenkey";

  // determine if the user/password can be authenticated and fire an event when finished
  login(username, password) {
    let data = { username: username, password: password };
    // remove any existing auth tokens from local storage
    this.stor.remove(this.AUTHTOKEN);
    // the important bit, contact the WP end point and ask for a token
    this.http.post('/server/wp-json/jwt-auth/v1/token', data).map(res => res.json())
      .subscribe(response => {
        // great we are authenticated, save the token in localstorage for future use
        this.stor.set(this.AUTHTOKEN, response.token);
        // and start using the token in every subsequent hhtp request to the WP server
        this.http.addHeader('Authorization', 'Bearer ' + response.token);
        // fire an event to say we are authenticated
        this.events.publish('user:login');
      },
      err => console.log(err)
      );
  }

/src/providers/http-client.ts

The HttpClient class has a very simple purpose; inject our authentication header into every Get and Post operation we make to the WordPress server.

// inject the header to every get or post operation
  get(url) {
    return this.http.get(url, {
      headers: this.headers
    });
  }
  post(url, data) {
    return this.http.post(url, data, {
      headers: this.headers
    });
  }

/src/providers/word-press-provider.ts

The WordPress provider has a single function: try to post the score and report data to WordPress.

The ‘createReport’ function:

  • Sends a message to the app to tell it that a save operation has started (for the purpose of showing spinners etc).
  • Sets the JSON data required by the WordPress REST API posts call (the full range of options can be seen here).
  • Posts the information to our WordPress website.
  • Gets back a success/failure message.
  • Lets the App know we have finished the save.
createReport(score: string, report: string) {
    // let the app know we have started a save operation
    // to show spinners etc
    this.events.publish('wordpress:savestatus', { state: 'saving' });
    // set the JSON data for the call
    // see https://developer.wordpress.org/rest-api/reference/posts/#create-a-post for options
    let data = {
      title: score,
      excerpt: report,
      content: report,
      status: 'publish'
    };
    // the important bit, make a request to the server to create a new post
    // The Authentication header will be added to the request automatically by our Interceptor service
    this.http.post('/server/wp-json/wp/v2/posts', data).subscribe(data => {
      // tell the app that the operation was a success
      this.events.publish('wordpress:savestatus', { state: 'finished' });
      this.events.publish('wordpress:createdreport');
    }, error => {
      this.events.publish('wordpress:savestatus', { state: 'error', message: error });
    });
  }

/pages/login/login.ts

The login page is very simple. When the login button is pressed, the username and password input in the textboxes are passed to our UserProvider service.

username: string;
  password: string;
  constructor(public UserProvider: UserProvider) {
  }
  login() {
    this.UserProvider.login(this.username, this.password);
  }

/pages/report/report.ts

Again the report page is very simple. When the report button is pressed, the score and report input in the textboxes are passed to our WordPress service.

constructor(private events: Events, private wordpress: WordPressProvider, private user: UserProvider, private loadingCtrl: LoadingController, private toastCtrl: ToastController) {
    this.createLoader();
    this.listenToWordPressEvents();
  }
  createReport() {
    this.wordpress.createReport(this.score, this.report);
  }

 

Any Questions?

That’s basically all there is to it.

If you have any questions, or any amendments that I can make to the Github repo, then please comment below….

12 thoughts on “WordPress REST API – Part 4 – Ionic 3

  1. Hello and thank you for taking the time to create this great tutorial/instruction.

    All works fine it seems but when I post a score to my wordpress site it get the “Error saving the report”

    Where is this saving to? Is this creating a new post in the WP site?

    • Hi Jason,
      Thanks for trying the sample out. Are you able to see the error that is being returned from the http call?
      If using Chrome, press f12, go to the network tab and see what error is returned when you try to submit.
      Conor

          • Hello Conor,

            I am able to logout and then log back in. Here are the contents of my ionic.config.json:

            {
            “name”: “wp-rest-api-ionic2”,
            “app_id”: “”,
            “proxies”: [
            {
            “path”: “/server”,
            “proxyUrl”: “https://mycompleteweb.net”
            }
            ],
            “type”: “ionic-angular”,
            “integrations”: {}
            }

            Thank you again for your help

  2. Carl

    I’m having the same problem as Jason. Doesn’t matter what role I assign to user. No problems logging in but can’t create reports. “Error saving report” message and console displays “rest_cannot_create”, “status: 401”, “Sorry, you are not allowed to create posts as this user.”

  3. fabian

    Hi, thanks a lot for this tutorial, unfortunately i always get the missing “Access-Control-Allow-Origin” on login. I tried everything but it is not working, do you have any idea?
    Thanks a lot.

  4. LVjp

    HI. I’m a newbie with Ionic 3. My learning is ok. But when i’m making a signup feature in my app. I have a problem with authentication in header. Can you show me how to do it?

  5. sawan

    Hi,
    Conor,
    Hope you are doing well,
    This is Sawan, I am new into the ionic hybrid development, I regularly follow your blog,
    I Read your blog post for Ionic +Wordpress using jwt authentication, I found it very useful stuff,
    However, I am middle of making my WordPress blog to a Hybrid App, I am totally stuck in middle,
    So, I thought you are the best person who can guide me on this,
    Below are few points in which I want take your advice or guidance,
    1. first of all I want to put login & signup page as first page (which will authenticate from my online WordPress blog), which I already got from your tutorial, then after login authentication with jwt.
    2. I want to authenticate my WordPress posts because in my posts in WordPress only logged in user can see the posts and make comments,
    3.Also want to register users from my App,
    4. Also need the option to create the comments & Posts,
    5. I have one more concern which is my 90% of posts are in embedded pdf post format, so how can I put that on my ionic posts,
    I know am seeking many things from you but I know only you can help me out.
    I will really appreciate your help, please also refer online materials or blog posts or book, magazine etc. for the above, because I am like a beginner

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.