The final app directory structure will look as follows:

meetupblast/

|_ _ _ _ assets/style.css /* style file */

|_ _ _ _ bower_components/ /* web lib deps */

|_ _ _ _ node_modules/ /* react transpile deps */

|_ _ _ _ src/ /* React and .js files */

| |_ _ _ _ app.js /* project root file */

| |_ _ _ _ helper.js

| |_ _ _ _ request.js

| |_ _ _ _ container.jsx

| |_ _ _ _ filterContainer.jsx

| |_ _ _ _ tag.jsx

| |_ _ _ _ user.jsx

| |_ _ _ _ userImg.jsx

|_ _ _ _ index.html /* main code file */

|_ _ _ _ gulpfile.js /* build file */

The codebase can be accessed at the meetupblast github repo. Or you can follow the remaining tutorial to see how we build it step by step.

Step 0: Initial Project Setup

We use bower_components for managing library dependencies for bootstrap, appbase-js and typeahead.js. If you haven’t used it before, it’s a neat package manager for the web.

bower init /* follow the interactive setup to create bower.json */

bower install --save bootstrap

bower install --save appbase-js

bower install --save typeahead.js

We will use browserify and reactify, two node_modules along with gulp, a streaming build for transpiling all the React .jsx files we will soon be adding to our codebase into javascript.

npm init /* follow the interactive setup to create package.json */

npm install --save browserify

npm install --save reactify

npm install --save gulp (if you don't already have it)

If you haven’t used gulp before or would like to learn more about how the transpiling process works in greater depth, checkout this spot on tutorial by Tyler McGinnis on the topic.

Next, we will configure the gulpfile to read all our React files.

A gulp file typically has one or more build tasks. We define the transpiling task browserify, which reactifies all the .jsx files starting from src/app.js into a single dist/main.js file. We will run the gulp build in the next step.

This is how the project tree should look at this point — files at step 0.

Step 1: Initializing Project Files

Next, we will initialize the project files, assets folder and start writing the index.html.

touch index.html

mkdir assets && touch assets/style.css

mkdir src && cd src

touch app.js request.js helper.js

touch container.jsx filterContainer.jsx tag.jsx user.jsx userImg.jsx

We recommend taking the stylesheet file from below and paste it as is into assets/style.css file.

Next, we will use our project setup files and call them from index.html.

Now that we have initialized all the project files, let’s transpile our non-existent .jsx files and run the app.

gulp browserify

/* If you see any missing node modules like 'vinyl-source-stream', add them with an npm install command */

npm install --save vinyl-source-stream

You should now see a dist/ folder generated in the project root with a file called main.js (as expected from our gulp build process).

Let’s run the app at this point using

python -m SimpleHTTPServer 3000

Step 1: A blank screen page created using our project setup

Your project tree at this point should look like this — project tree at step 1.

Step 2: Writing UI Components with React

Our project is setup with all the necessary files, we have a good handle on the React transpiling process using gulp. Now’s the time to dive into the src/ codebase.

app.js is the entry point. In case you missed it, we used this file path in our gulp browserify build process too.

helper.js is a helper file, we recommend you get it from here and paste it as is.

It requires container.jsx file, which we declare inside the app.js file.

Before delving into the React components, here’s a small primer on them. React components are the defining units of code organization (like classes in Java) in React. A component can inherit another component, have child components and can be published on the interwebs.

A component is always defined with a React.createClass({specObject}) invocation, where the specObject should have a mandatory render() method. It can also contain other methods as well. This is a good reference to whet your appetite about a component’s spec and lifecycle.

If you have never created a React component based app before, we recommend checking out this status feed app tutorial.

Enough said, let’s take a look at out codebase.

Container is the main component. It responsible for keeping the state of three variables:

users — an array of RSVP feeds that are being streamed by appbase.io CITY_LIST — an array of current city selection for filtering which feeds need to be streamed TOPIC_LIST — an array of current topic selection for filtering feeds by topics.

If we wanted to include other UI elements to filter feeds by (for instance, dates of meetups), we would similarly use another variable keep it’s state in the container.

The container is divided into two sub-components:

FilterContainer component which creates the UI widget and manages the interaction flow to update the cities and topic, and User component is responsible for displaying the individual feed element’s UI.

Image: City and Topic UI elements built with FilterContainer and Tag components

In the FilterContainer, we initialize the RSVP feed stream via the fire_response method. It contains the Tag component to reuse the UI elements for building the city and topic list views.

You can copy and paste the Tag component’s code from here:

Let’s take a look at the User component.

A lot of the code here is in making sure we give it the proper styling layout. By now, it should be clear how components in React. They are not very different from the abstractions offered by Object Oriented Programming languages like Java.

This component uses one sub-component called UserImg. It’s a very simple component that uses a default puppy image when a user’s image URL in the RSVP JSON doesn’t resolve.

This is the entirety of our React code: We should have app.js, container.jsx, filterContainer.jsx, tag.jsx, user.jsx and userImg.jsx files.

We are missing one last important file before we get to see the working demo, request.js. We use the appbase-js lib here for defining live queries on the RSVP feed data. We recommend getting it as is from the link below to get to the functional demo.

Let’s run the app now.

gulp browserify

python -m SimpleHTTPServer 3000

The project tree at this step should resemble the final project. You can also see the live demo at appbaseio-apps.github.io/meetupblast-react.

How Live Queries Work

Earlier, we skipped an important part of explaining how the live queries work. Let’s take a look at it here.

There are three important queries happening in the UI:

Streaming RSVP feeds live filtered by the user selected cities and topics. Generating the list of cities and topics. Paginating to show historical data when user scrolls down.

Let’s see how to do the first one.

// connecting to the app using our unique credentials. We will use these since the backend worker is configured to update this app, but you can change this by creating your own app from appbase.io dashboard.

var appbaseRef = new Appbase({

appname: "meetup2",

url: "https://qz4ZD8xq1:a0edfc7f-5611-46f6-8fe1-d4db234631f3@scalr.api.appbase.io"

}) // Now let's get the initial feed data

var response = appbaseRef.search({

type: "meetup",

size: 25,

body: {

query: {

match_all: {}

}

}

})

response.on("data", function(data) {

console.log("25 results matching everything", data.hits.hits)

// all initial data is returned in an array called hits.hits. You can browse the data object to see other interesting meta data like the time taken for the query.

});

When you run the above snippet in the console, you should see an array of size 25. Now, this is great but how do we continuously stream new RSVP feeds as they are indexed in the backend. Here’s how:

// Let's subscribe to new data updates. searchStream() works exactly like search() except it only returns new data matching the query is indexed or modified.

var streamResponse = appbaseRef.searchStream({

type: "meetup",

body: {

query: {

match_all: {}

}

}

})

streamResponse.on("data", function(sdata) {

console.log("I am a new data", sdata._source)

// all new data is returned as JSON data in streams

})

Image: Browser console output when running the above script

We now know how live queries work with appbase.io APIs.

The interesting part here is the JSON query object defined in the search() and searchStream() methods. We can change this query object to only showing RSVPs that match a white list of cities and/or topics. Anything that can be specified with Elasticsearch’s Query DSL can be queried live with appbase.io.

This is exactly what request.js does. It also creates a list of top 1000 cities and topics at the start of the app based on aggregating all the RSVPs indexed in the last month. See https://github.com/appbaseio-apps/meetupblast-react/blob/master/src/request.js#L17.

You can read more about appbase’s APIs here or check out a whole host of interesting live querying based apps at appbase.io’s community page.