Creating a Trivia App with Ignite — Part I

Robin Heinze
Red Shift
Published in
5 min readJul 24, 2019

--

UPDATE 1/09/2024: This has now been updated to be compatible with Ignite Exp[ress]o (9.3.1).

If you’ve never used MobX State Tree or TypeScript, the Ignite stack can be a bit unfamiliar! If you’re curious why we love this stack, take a look at this doc.

In this post, we’ll go through the steps of creating the data model for a trivia app to illustrate how to use our stack with real examples.

(Psst, spoiler alert! If you’d like to follow along with real live code, check out the finished app!)

First things first, let’s Ignite our new app! Check out the ignite-cli documentation to read up on everything Ignite can do!

npx ignite-cli new IgniteTrivia --install-deps --remove-demo

As the Ignite commands run you can just accept the the defaults for the remaining prompts:

✅ What bundle identifier? · com.ignitetrivia
✅ Where do you want to start your project? · /Users/jpoliachik/code/IgniteTrivia
✅ Choose a workflow: · Expo Go
✅ Do you want to initialize a git repository? (Y/n) · Yes
✅ Which package manager do you want to use? · yarn

After Ignite finishes running, cd into the folder and run yarn ios or yarn androidand you should see something like this:

Ignite Welcome Screen

Defining Our Models

Next, let’s start building our data models. We’re going to use The Open Trivia Database as our data source, so we’ll build our models to match that data.

Question

We need a question model! Each question has the following properties:

id, category, type, difficulty, question, correctAnswer, incorrectAnswers

Let’s create the MobX State Tree (MST) model:

npx ignite-cli generate model question

This will create two files in our models folder, app/models , which contains a few files:

Question.ts
Question.test.ts

We won’t be writing unit tests quite yet, so we’ll focus on Question.ts

app/models/Question.ts

This file has a couple different parts. First there’s QuestionModel, which is the heart of this file. It’s the MST model definition. Each model instance has properties, like a regular JS object, but it also has views (computed values), and actions.

At the bottom of the file, we define some TypeScript interfaces which will help TypeScript to know about the shape of our data as we use it throughout the app.

We’ll focus on properties first, so let’s add the properties we want each Question to have:

app/models/question.ts

Let’s unpack this a bit.

We have id, which is types.identifier. This is MST’s version of a primary key. It has to be unique, and it allows you to do some helpful things like reference your model instance by only its identifier. You can read a bit more about identifiers here.

Then, we have some string properties: category, question, and correctAnswer. These are all free-form text values, and we’ve made them optional by using types.maybe(). That means these values can be undefined.

We also have the property incorrectAnswers which is an array of strings. Instead of types.maybe(), we’ve used types.optional(). This allows us to not specify a value for this property, but instead of being undefined, it will take a default value of [].

Finally, we have typeand difficulty which is are both enumerations. This forces the value to be one of a predetermined list of values, in the case strings.

Question Store

Since we’ll be listing more than one trivia question, we need a place to store a list of them. So let’s create QuestionStore.

npx ignite-cli generate model question-store

IGNITE TIP 🎉: If you Ignite apps as often as we do, you can abbreviate generate as g, like npx ignite-cli g model <model-name>

This file looks a lot like question.ts did when we first generated it, but we’re going to add different properties. For now, it only has one: an array of type QuestionModel. This will be an array of MST instances. We may decide we need more properties later, but this will be enough to get started.

Generate QuestionStore

Hooking up the API

Okay, we have some models describing the shape of data that we want. Now let’s get some data.

API Service

Ignite comes with an API service all ready to customize, so let’s customize it.

Changes to config.dev.ts, api.ts and api.types.ts:

config.dev.ts within the config folder
api.ts file within the services/api folder
api.types.ts file within the services/api folder

Here’s what we did:

  • We updated the base URL in app/config/config.dev.ts
  • Updated the function return types to use QuestionSnapshotOut. Snapshots are the serialized version of MST models, without all the dynamic features like views, and actions. You can think of snapshots as the immutable, plain JS object version of your MST model. This type definition lives in api.types.ts.
  • Added a uuid to each record with react-native-uuid. You can add it to your project by running yarn add react-native-uuid.

Fetching the Data

Now that our API service is setup, let’s tell our models how to call the API and populate data into our store.

It’s time to make our first MST action.

But first, let’s take a look at something that comes standard in our generated Question Store Model.

You’ll notice that there’s already an action .actions(withSetPropAction). This is a helper will allow you to set property values directly while retaining type safety and also is executed in an action. This is useful because often you find yourself making a lot of repetitive setter actions that only update one prop.

QuestionStore.ts file with the getQuestions action

We’ve added a new action! getQuestions calls the API method to get the array of snapshots from the API, and then we set the questions prop with the setProp helper function. Because of this helper, we’re able to await for the api.getQuestions call to resolve and set our prop to those results, instead of the mobx-state-tree flow generator function syntax.

That’s it for Part I! We now have a solid data model, and a way to populate our store from an external API. Next time, in Part II, we’ll consume our data by hooking up a UI!

Robin Heinze is a senior software engineer building React Native apps at Infinite Red, a mobile/web app design and development agency. Follow her on Twitter or Github.

--

--