Connecting Angular and the WordPress API with wp-api-angular

Share this article

Connecting Angular and the WordPress API with wp-api-angular

In this tutorial, you’ll learn how to work with the wp-api-angular library that allows you to interact with the WordPress API from Angular 2+ applications. This library supports all major WP resources including users, posts, comments, media, taxonomies etc. It’s also quite simple to use, so you’ll get the idea in no time.

To see the library in action, we’re going to code the following features:

  • Authentication using JWT
  • Listing the users
  • Listing the posts
  • Creating and editing the posts
  • Deleting the posts

By the end of the article, you’ll become familiar with this library and will be ready to use it on your own.

The source code for this tutorial is available on GitHub.

I’ll assume you’re using Angular 5, but all explained concepts should be valid for Angular 2 as well.

Laying Foundations

Setting Up WordPress

Before we proceed to writing the code, there are a couple of things to take care of. First of all, note that the API we’re going to utilize works only with the self-hosted version of WordPress. For the web version (which can be configured via the WordPress site), there’s a separate API that has many similar concepts, though it’s still quite different.

You also have to enable permalinks — which is required for the API client to work correctly. For Nginx, you’ll need to add the following line to the nginx.conf file:

try_files $uri $uri/ /index.php?$args;

More detailed information and explanations on how to enable permalinks can be found in this WordPress Codex guide.

Lastly, we should take care of WordPress security which, as they say, is above all. For that, a special plugin called JWT Authentication is required. We’re going to use it in order to authenticate our API client with the help of special tokens (an approach that’s quite common these days).

That’s pretty much it. If you’d like to learn more about the WordPress API in general, skim through this article. When you’re ready, proceed to the next step and let’s see the Angular WordPress client in action!

Bootstrapping an Angular Application

Now that we have WordPress prepared, create a new Angular application by running:

ng new wp-api

This is going to create a skeleton for the application. We’re not going to discuss its structure thoroughly, but you may find more information in our Angular series.

Next, cd into the directory and install the library itself:

cd wp-api
npm install -g typings
npm install wp-api-angular --save

Now we need to import the proper components inside the src/app/app.module.ts file:

// ... other imports
import { Http } from '@angular/http';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import {
  WpApiModule,
  WpApiLoader,
  WpApiStaticLoader
} from 'wp-api-angular';

WpApiModule should also be added to the imports block. Note that we must use an exported factory for AoT compilation or Ionic:

// ... imports

@NgModule({
  declarations: [
        // ... omitted
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule, // <---
    WpApiModule.forRoot({ // <---
      provide: WpApiLoader,
      useFactory: (WpApiLoaderFactory),
      deps: [Http]
    })

  ]
    // ...
})

Here’s the factory itself:

export function WpApiLoaderFactory(http: Http) {
  return new WpApiStaticLoader(http, 'http://YOUR_DOMAIN_HERE/wp-json/wp/v2/', '');
}

Don’t forget to provide your own domain name here!

Lastly, let’s also add some imports to the app.components.ts file:

import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { NgForm } from '@angular/forms';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { Headers } from '@angular/http';

// ...

We’ll need NgForm to craft forms, HTTP modules to interact with the API and Headers to authenticate the client.

The initial setup is done and we can proceed to the next section.

Authentication

Before interacting with the API, we need to introduce an authentication mechanism. As I already mentioned above, a token-based authentication will be employed, so let’s add a token variable to the app.components.ts:

export class AppComponent {  
    token = null;
    // ...
}

Also, tweak the app.component.html file by adding a new block:

<div>
  <app-authentication [(token)]='token'></app-authentication>
</div>

In order for this to work, a separate component is required so generate it now:

ng generate component authentication

Import the necessary modules inside the src/app/authentication/authentication.component.ts file:

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { HttpClientModule, HttpClient } from '@angular/common/http';
// ...

The authentication process is going to be very simple: a user should enter their login and password, submit the form, and a special token will be returned if the credentials are correct. This token will then be utilized to perform API requests. Therefore, let’s draft a user and add input and ouput for the AuthenticationComponent:

// ...
export class AuthenticationComponent implements OnInit {
  user = {
    login: '',
    password: ''
  }
  @Input() token;
    @Output() tokenChange = new EventEmitter<string>();

    // ...
}

Of course, you may define the user as a model, but for the purposes of this demo it’s not mandatory. As for the constructor, pass the HttpClient to it:

// ...
constructor( private http: HttpClient ) { }

Next code the auth method. It’s as simple as sending a POST request to the proper URL with the credentials and waiting for the response:

// ...
auth() {
  this.http.post('http://YOUR_DOMAIN/wp-json/jwt-auth/v1/token', {
    username: this.user.login,
    password: this.user.password
  }).subscribe((data) => {
    if (data['token']) { // if token is returned
      this.token = data['token'];
      this.tokenChange.emit(this.token);
    }
  });
}

Once again, don’t forget to insert your domain name into the URL.

The component is ready, and the last thing to do in this section is create the corresponding form. It should be displayed only if the token is null. When the form is submitted, the auth method should be called:

<form *ngIf='token == null' (ngSubmit)='auth()'>
</form>

Flesh the form out by adding two fields and a Submit button:

<form *ngIf='token == null' (ngSubmit)='auth()'>
    <div class='form-group'>
      <label for='login'>Login</label>
      <input type='text' class='form-control' [(ngModel)]='user.login' name='login' id='login' required>
    </div>

    <div class='form-group'>
      <label for='password'>Password</label>
      <input type='password' class='form-control' [(ngModel)]='user.password' name='password' id='password' required>
    </div>

    <button type="submit" class="btn btn-success">Submit</button>
</form>

That’s it! The authentication feature is finished, and we may start playing with the API itself.

Listing the Users

Usually, reading via the API is simpler than writing, so let’s try to list the users of our website powered by WordPress. Create a new UserList component:

ng generate component user-list

Inside the src/app/user-list/user-list.component.ts you’ll need to import the WpApiUsers module as well as some other modules:

import { Component, OnInit, Input } from '@angular/core';
import { WpApiUsers } from 'wp-api-angular';
import { Headers } from '@angular/http';
// ...

We’re going to store users inside the users array, which is initiallity empty:

// ...
export class UserListComponent implements OnInit {
    users = [];
}

Pass WpApiUsers into the constructor and call a getUserList method:

// ...
constructor( private wpApiUsers: WpApiUsers ) {
  this.getUserList();
}

Now we need to code the getUserList. Every method presented by the API client returns an observable which can be converted to a promise using toPromise. So, to get a list of all users we should call the getList method, convert it to a promise, and assign the users variable with the returned array:

// ...
getUserList() {   
  this.wpApiUsers.getList()
  .toPromise()
  .then( response => {
    let json: any = response.json();
    this.users = json;
  })
}

As you see, nothing complex here. Interestingly, we don’t even need a token in order to perform this method. Therefore, simply render the users in a cycle:

<div>
  <h2>Users:</h2>
  <div *ngFor="let user of users">
     Name: {{user.name}}
  </div>
</div>

The user-list component should be added to the app.component.html file:

<!-- ... -->
<div>
  <user-list></user-list>
</div>

Working With Posts

Creating Posts

Now let’s try to implement a somewhat more complex feature and allow users to add new posts via the API. Create a separate post-new component:

ng generate component post-new

Import the necessary modules inside the filesrc/app/post-new/post-new.component.ts file:

import { Component, OnInit, Input } from '@angular/core';
import { WpApiPosts } from 'wp-api-angular';
import { Headers } from '@angular/http';
// ...

The WpApiPosts module is going to be the main star here.

Next, provide the token as an input and draft a post model:

// ...
export class PostNewComponent implements OnInit {
  @Input() token;
  new_post = {
    title: '',
    content: '',
    status: 'publish'
    }
}

At the very least, each post should contain a title, some content, and the status (which we hard-code as publish to instantly publish the new post).

A constructor should accept the WpApiPosts:

// ...
constructor( private wpApiPosts: WpApiPosts ) { }

Now let’s craft a method to add the post. First, code the authentication logic by setting the Authorization header:

// ...
createPost() {       
  let headers: Headers = new Headers({
    'Authorization': 'Bearer ' + this.token
    });
}

Now we can simply take the headers variable and pass it to the create method of the WpApiPosts module:

// ...
createPost() {       
  let headers: Headers = new Headers({
    'Authorization': 'Bearer ' + this.token
  });

  this.wpApiPosts.create(this.new_post, { headers: headers })
  .toPromise()
  .then( response => {
    console.log(response);         
  })
}

What about the form? Well, it’s quite simple really:

<!-- src/app/post-new/post-new.component.html -->
<div>
  <h2> Post Creation </h2>
    <form (ngSubmit)='createPost()'>
      <div class="form-group">
        <label for="title">Post title</label>
        <input type="text" class="form-control" [(ngModel)]='new_post.title' name='title' id="title" required>
      </div>

      <div class="form-group">
        <label for="content">Post content</label>
        <textarea class="form-control" id="content" required [(ngModel)]='new_post.content' name='content'></textarea>
      </div>

      <button type="submit" class="btn btn-success">Submit</button>
    </form>
</div>

When the form is submitted, we call the createPost method.

Don’t forget to render the post-new component:

<!-- app.component.html -->
<!-- ... -->
<div>
  <h3 *ngIf='token == null'> Please, authorize to create a post </h3>
  <post-new *ngIf='token' [token]='token'></post-new>
</div>

We check that the token is set, and if not, we ask the user to authenticate.

Listing the Posts

Okay, we’ve added the ability to create the posts. Why don’t we also display them on the page? Create yet another component:

ng generate component post-list

Import the necessary modules, including WpApiPosts inside the src/app/post-list/post-list.component.ts file:

import { Component, OnInit, Input } from '@angular/core';
import { WpApiPosts } from 'wp-api-angular';
import { Headers } from '@angular/http';
// ...

Provide the input and the posts array:

// ...
export class PostListComponent implements OnInit {
  @Input() token;
    posts = [];
}

Code the constructor that should call the getPosts method:

// ...
constructor(private wpApiPosts: WpApiPosts) {
  this.getPosts();
}

We don’t need to authenticate to fetch the posts, so let’s use the same approach as before:

// ...
getPosts() {
  this.wpApiPosts.getList()
  .toPromise()
  .then( response => {
    let json: any = response.json();
    this.posts = json;
  });
}

Now render the array of posts:

<!-- src/app/post-list/post-list.component.html -->
<div>
  <h2>Latests Posts:</h2>
  <hr>
  <div *ngFor='let post of posts'>
    <h1 [innerHTML]='post.title.rendered'></h1>
    <p [innerHTML]='post.content.rendered'></p>
    <hr>
  </div>
</div>

Lastly, display the component:

<!-- app.component.html -->
<!-- ... -->
<div>
  <post-list [token]='token'></post-list>
</div>

Destroying the Posts

Next, I’d like to add an ability to destroy the posts. This feature can be implemented in the same PostList component. Simply add a Delete button next to each post:

<!-- src/app/post-list/post-list.component.html -->
<div>
  <h2>Latests Posts:</h2>
  <hr>
  <div *ngFor='let post of posts'>
    <h1 [innerHTML]='post.title.rendered'></h1>
    <p [innerHTML]='post.content.rendered'></p>
        <button *ngIf='token' (click)='deletePost(post.id, $index)'>Delete</button>
    <hr>
  </div>
</div>

Note that this button is displayed only if the token is present. Also, tweak the component by adding the deletePost method:

// src/app/post-list/post-list.component.ts
// ...
deletePost(id: number, index: number) {
  let headers: Headers = new Headers({
    'Authorization': 'Bearer ' + this.token
  });

  this.wpApiPosts.delete(id, { headers: headers })
  .toPromise()
  .then( response => {
    if (response['ok'] == true) {
      this.posts.splice(index,1);
    }       
  })
}

Basically, nothing new here. We’re adding the token to the headers and call the delete method which accepts the post’s ID and its index in the posts array. If the request succeeded, remove the post from the array.

Editing the Posts

The last feature we’re going to introduce today is the ability to edit the posts. Let’s create a new component:

ng generate component post-edit

This component will be referenced from the PostList. Specifically, I’d like to add an Edit button next to each post and render the PostEdit template whenever it’s clicked:

<!-- src/app/post-list/post-list.component.html -->
<div>
  <h2>Latests Posts:</h2>
  <hr>
  <div *ngFor='let post of posts'>
    <div *ngIf='editingPost != post; else postEdit'>
    <h1 [innerHTML]='post.title.rendered'></h1>
    <p [innerHTML]='post.content.rendered'></p>
    <button *ngIf='token' (click)='deletePost(post.id, $index)'>Delete</button>
    <button *ngIf='token' (click)='updatePost(post)'>Edit</button>
    <hr>
  </div>
</div>

<ng-template #postEdit>
  <post-edit [post]='editingPost' [token]='token' (finish)='editingPost = null; getPosts()'></post-edit>
</ng-template>

Tweak the PostListComponent by introducing an editingPost variable and an updatePost method, which is going to assign the editingPost with a proper value:

// src/app/post-list/post-list.component.ts
// ...
export class PostListComponent implements OnInit {
  @Input() token;
  posts = [];
    editingPost = null;

    updatePost(post) {
      this.editingPost = post;
    }
}

Proceed to the PostEditComponent and import all the required modules:

// src/app/post-edit/post-edit.component.ts
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { WpApiPosts } from 'wp-api-angular';
import { Headers } from '@angular/http';
// ...

This component is going to have two inputs: the token and the actual post to edit. Also, we’ll have an output (EventEmitter):

// ...
export class PostEditComponent implements OnInit {
  @Input() token;
  @Input() post;
  @Output() finish = new EventEmitter<void>();
  post_edit = {
    title: '',
    content: ''
    }
}

As soon as the component is initialized, assign the post_edit variable with the proper title and content taken from the post variable:

// ...
ngOnInit() {
  this.post_edit['title'] = this.post.title.rendered;
  this.post_edit['content'] = this.post.content.rendered;
}

Now code the updatePost method, which is going to perform authentication. Update the post and emit an event:

// ...
updatePost() {
  let headers: Headers = new Headers({
    'Authorization': 'Bearer ' + this.token
  });

  this.wpApiPosts.update(this.post.id, this.post_edit, { headers: headers })
  .toPromise()
  .then( response => {
    this.finish.emit(null);      
  })
}

Note that the update method accepts both the post’s ID and the new value for the title and content.

Here’s the form to edit the post:

<!-- src/app/post-edit/post-edit.component.html -->
<div>
  <h2> Post Editing </h2>
    <form (ngSubmit)='updatePost()'>
      <div class="form-group">
        <label for="title">Post title</label>
        <input type="text" class="form-control" [(ngModel)]='post_edit.title' name='title' id="title" required>
      </div>

      <div class="form-group">
        <label for="content">Post content</label>
        <textarea class="form-cont  rol" id="content" required [(ngModel)]='post_edit.content' name='content'></textarea>
      </div>

      <button type="submit" class="btn btn-success">Submit</button>
    </form>
</div>

This’s it: the editing feature is ready! You may now boot the server by running:

ng serve --open

and play with the app to make sure everything is working fine.

Conclusion

In this article, we’ve discussed the usage of the WordPress API client for Angular. We’ve seen it in action by introducing the authentication feature, listing the users and posts, as well as by adding ability to create and manipulate the posts. This client allows you to work with other resources like media and comments, but all these interactions are very similar to the ones we’ve talked about here.

Hopefully you’re now ready to apply the information presented here into practice, but don’t hesitate to send me your questions! As always, thanks for staying with me and until the next time.

Frequently Asked Questions on Integrating Angular with WordPress

How can I integrate Angular with WordPress using WP API?

Integrating Angular with WordPress using WP API involves a few steps. First, you need to install and activate the WP API plugin in your WordPress dashboard. Then, in your Angular project, you need to install the HTTP client module which allows you to make HTTP requests. After that, you can use the HTTP get() method to fetch data from your WordPress site. Remember to replace the URL with your own WordPress site URL.

What are the benefits of integrating Angular with WordPress?

Integrating Angular with WordPress offers several benefits. Angular is a powerful framework that allows you to build dynamic and interactive web applications. By integrating it with WordPress, you can leverage the robust content management capabilities of WordPress and the advanced features of Angular to create a more engaging and user-friendly website.

Can I use Angular with a headless WordPress setup?

Yes, you can use Angular with a headless WordPress setup. In a headless WordPress setup, the front-end and back-end are decoupled, which means you can use any technology you want for the front-end while still using WordPress for content management. This allows you to use Angular for building the front-end of your website.

How can I host an Angular app inside a WordPress site?

Hosting an Angular app inside a WordPress site involves a few steps. First, you need to build your Angular app and generate a production-ready version of it. Then, you need to upload the generated files to your WordPress server. After that, you can create a new page in WordPress and include the Angular app in it using a shortcode.

What are the challenges of integrating Angular with WordPress?

Integrating Angular with WordPress can be challenging, especially if you’re not familiar with both technologies. Some of the challenges include dealing with CORS issues, handling authentication, and managing state between WordPress and Angular. However, with proper planning and understanding of both technologies, these challenges can be overcome.

How can I handle authentication when integrating Angular with WordPress?

Handling authentication when integrating Angular with WordPress can be done using JWT (JSON Web Tokens). You need to install and activate the JWT Authentication for WP REST API plugin in your WordPress site. Then, in your Angular app, you can use the HttpClient module to send a POST request to the /wp-json/jwt-auth/v1/token endpoint with your username and password to get a token.

Can I use Angular with WordPress plugins?

Yes, you can use Angular with WordPress plugins. However, not all plugins may work as expected, especially those that rely heavily on jQuery or other JavaScript libraries. It’s recommended to test each plugin thoroughly to ensure compatibility.

How can I deal with CORS issues when integrating Angular with WordPress?

Dealing with CORS (Cross-Origin Resource Sharing) issues when integrating Angular with WordPress can be done by adding the appropriate headers in your WordPress server. You can do this by modifying the .htaccess file or using a plugin like the WP REST API – OAuth 1.0a Server plugin.

Can I use Angular with WordPress themes?

Yes, you can use Angular with WordPress themes. However, since Angular is a front-end framework, it may not work well with some themes that rely heavily on PHP for rendering the front-end. It’s recommended to use a basic theme or a headless WordPress setup when using Angular.

How can I manage state between WordPress and Angular?

Managing state between WordPress and Angular can be done using a state management library like NgRx or Redux. These libraries allow you to manage and track the state of your app in a predictable way, making it easier to debug and test.

Ilya Bodrov-KrukowskiIlya Bodrov-Krukowski
View Author

Ilya Bodrov is personal IT teacher, a senior engineer working at Campaigner LLC, author and teaching assistant at Sitepoint and lecturer at Moscow Aviations Institute. His primary programming languages are Ruby (with Rails) and JavaScript. He enjoys coding, teaching people and learning new things. Ilya also has some Cisco and Microsoft certificates and was working as a tutor in an educational center for a couple of years. In his free time he tweets, writes posts for his website, participates in OpenSource projects, goes in for sports and plays music.

angularAngular Tutorialsangular-hubangularjsnilsonjrest apiWordPress
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week