React Native and Drupal 8

List Drupal 8 content in a React Native App

React Native is one of the fastest growing frameworks out there, and I recently had some spare time to mess around with it and how I could integrate it with Drupal 8 in order to build a simple App.

In this quick tutorial, I will get you to list some basic content from Drupal in a React Native App, ready to deploy into the Play/Apple Store.

There are a few requirements for this:

  • A basic understanding of Drupal, including Views and enabling/disabling Modules.
  • A Drupal 8 website with a public URL that has a few sample bits of content.
  • A free account on Expo.io, as we will be using their Snack online IDE
  • A smart phone with the Expo.io app installed so we can quickly test out our code

First up, lets get the Drupal website setup correctly.

Enable the ‘RESTful Web Services’ module, as well as Views and Views UI.

Create a new View, but rather than creating a block, we want to check the option for ‘Provide a REST export’ and click ‘Save and edit’.

First important step is to select a path like you would for a View Page.  I usually prefix mine with /api/, so lets set this one as /api/test.

Next, we need to check the format. Make sure it’s ‘Serializer’ and under settings ensure that JSON is checked.

Below that, rather than Entity, we want to use ‘Fields’.

After all that, you should see down in your Preview, a fairly simple JSON array.  You may want to alter which fields are being displayed, and if you are returning a Title, uncheck the ‘Link to content page’ option.  But that is simple basic Views stuff which I hope you should already know.

In my example I’m actually returning a list of Taxonomy terms, but again, that’s just your View configuration.  And my JSON is fairly simple:

[
  {"name":"Monday","tid":"34","short":"Mon"},
  {"name":"Tuesday","tid":"35","short":"Tue"},
  {"name":"Wednesday","tid":"36","short":"Wed"},
  {"name":"Thursday","tid":"37","short":"Thu"},
  {"name":"Friday","tid":"38","short":"Fri"},
  {"name":"Saturday","tid":"39","short":"Sat"},
  {"name":"Sunday","tid":"40","short":"Sun"}
]

Now, before we put Drupal down, we just want to make sure we can access the View and that it is working correctly.

After saving the view, simply load the URL you set in Path. NOTE: If this doesn’t work, try adding ?_format=json to the end of it.  If it’s still not working, something else is wrong…. Try Googling the error.

Once we have the JSON being displayed on that page, we no longer need to touch Drupal, as it’s serving up the content we want.

Open up Snack, and you will be given a fairly basic Hello World kind of Snack.

Now open the Snack App on your phone, login and it will show you your active Snacks.  Open it up on the phone just to be sure it’s working.

Now, let’s clean up and get ready to bring our Drupal content in.

Delete lines 18, 19 and 20 which should contain the <Card> and <AssetExample>.

And up in the list of Imports at the top, we should clean up lines 5 to 9, since we are no longer using those Assets.

At this point, if your phone still has the App open, it should now just read “Change the code in the editor…”

Now, we will make a kind of global variable where we can store our future JSON.

Under the ‘export default class’ line, add some space in, and include the following:

constructor(props) {
  super(props);
  this.state = {
    content: [],
  };
}

We can store data in ‘this.state’ and then retrieve it later.

Next up below the Constructor Props above, we will add in what is kind of considered an init() or document.ready().  It will run just before the render() function.

componentWillMount() {
}

Now, inside that function is where we will query our data and save it into the state array.

async function api_content() {
  const response = await fetch(
    'http://example.com.au/api/test',
    {}
  );
  const json = await response.json();
  return json;
}

This is a very simple and stripped down Asynchronous fetch request.

Now what we have the function to call to get the Data, we need to actually call it.  So below that, we want to add:

api_content().then(contentReturn => {
  this.setState({ content: contentReturn });
});

What this does is call the async function above, and whatever it returns will be inside the contentReturn variable.

So once we have that Variable, we simply setState it into our this.state.content that we created earlier.

And if everything has gone right, your phone App should just be showing the same white screen with text.  If there is an error,  be sure to review the above code again.

Phone with Data

Now, there is nothing left to do but show our content.

Down in the render() function, inside the <View> element I’m going add a .map, which is similar to a ForEach or a Loop.

{this.state.content.map(item => {
  return (
    <Text style={styles.paragraph}>{item.name}</Text>
  );
})}

This will loop through each of the returned items, and assign each to the variable ‘item’.  It then has it’s own return() function that in this instance returns the <Text> element using the item.name attribute.

And if we look back at our JSON from the start:

{"name":"Monday","tid":"34","short":"Mon"}

I have access to “name”, “tid” and “short”, so I could return any or all of them.

<Text style={styles.paragraph}>{item.name}, TID: {item.tid}</Text>

Now that you can list your Drupal content in your React Native App, there’s nothing you can’t do!

You can add some Contextual Filters to your view in order to query dynamic content from the site, you can use content returned from one View to then do on another View? List all users, then list all content edited by those users!

So many options!

 

Date posted:
06 November 2018
Authored by :
Toby Wild