React Native - Beautiful Horoscope App

Recently I was working on sample project that helps to sharpen my skill in React Native (RN), and I found an interesting API which related to horoscope. It was Aztro API, an open-source horoscope API. Hence, I decided to write myself a Horoscope App!

Screenshot of Horoscope App

Tech-stack

  1. React Native (of-course!) and React Hooks

  2. Redux & Redux-Saga

  3. Axios

Because of my company projects are using Redux and Redux-Saga, and I am still very weak on the concept, hence I decided to make the app with Redux and Redux-Saga as the app’s state management.

Redux & Redux Saga

Redux is one of the most popular state management framework for React application and Redux Saga helps to manage the side effect asynchronously. You may learn more on Redux and Redux Saga. (I am still beginner on these! 😃). Their explanation are pretty clear but real-life experience is always better than reading book!

Back to API, It was a POST request with 2 params, sign and day .

POST: https://aztro.sameerkumar.website?sign= <sign> &day= <day>

<!-- RESPONSE --> 
{"current_date": "November 1, 2021", "compatibility": " Cancer", "lucky_time": " 7am",
 "lucky_number": " 64", "color": " Spring Green", "date_range": "Mar 21 - Apr 20",
 "mood": " Relaxed", "description": "It's finally time for you to think about just
  one thing: what makes you happy. "}

Here is the axios POST request implementation.

That’s it! Simple API call right? but how can we integrate it into Redux?

There are 3 important parts: Actions, Reducers & Store

  1. Actions

As the API requested, there will 2 be request params sign & day and we created a type for it, API_REQUEST

2. Reducers

First, we defined our initial state where it contains loading , error & data . Then, we created a HoroscopeReducer that take current state, perform an action and return it with a new state. In the snippets, when we requesting from API, loading is set to true. If successfully get response, loading is set to false and data is set to response’s data. Meanwhile if error happens, error will be set to response’s error.

3. Store

Store is the place where hold the applicate state. Since horoscopeRequest is an async function, we can use Redux Saga to handle these operation.

We created a Saga watcher in generator function getHoroscope based on API_REQUEST actions and takeLatest will only take care of the latest sagas and automatically cancel any previous on-going sagas.

I had created a rootSaga in case there is any further sagas that can be merge into a single entry point for sagaMiddleware to run.

Finally, we create store with sagaMiddleware. Then run our rootSaga and render our application.

Render Application

After having store, we need a provider to bind our store to our application.

We are almost there! But how can we call our API in UI?

Since we only need to request API when selected a horoscope, we will request it in useEffect() (when it first launched the page & changing date). dispatch is used for request API.

Then, mapStateToProps is needed to map our state’s data into props, and connect mapStateToProps to our HoroscopeDetail .

Finally, we can get our state in HoroscopeDetail ‘s props — horoscopeModel !

UIUX design

There is 2 page in this application, which is Home & HoroscopeDetail .

In Home , I had created a FlatList to render horoscopeList (array of 12 zodiac) with customised HoroscopeCard .

In HoroscopeDetail , all the components are wrapped into SafeAreaView and ScrollView . Figure below shows the overall of the components used.

Result

iOS

Android

Conclusion

That’s all from me! Hope your guys enjoy reading my article and love what I had done. However, there is still some features to be enhance.

  1. Shared element transition for zodiac icon.

  2. Feature to share horoscope to your friends.

  3. AppWidgets to show today’s horoscope.

  4. And plenty more..

I had built a testing Android APK for you guys to download and try it out (check my Github link on bottom of the article)! Do drop me any feedback and please correct me if I have done anything wrong in this project. Happy React-Native-ing! 🍷

89