DEV Community

Cover image for How to create a Dailynow mobile app in few minutes with React-Native and Expo
ELABBASSI Hicham
ELABBASSI Hicham

Posted on

How to create a Dailynow mobile app in few minutes with React-Native and Expo

As a developer, you might want to know what's new in the tech area. I advise you the very useful Chrome/Firefox extension called Dailynow. You need to install this extension to quickly retrieve the API url. In this tutorial, we are going to create a very simple Dailynow mobile app with react-native and the Expo sdk/platform. I create a github repo for this tutorial.

The first thing we are going to do is to create an Expo account and download the Expo client mobile app. Play Store | App Store.

You can now log in to the expo client mobile app.

You're now ready to create the application!

Open a terminal, install the expo-cli globally, create an expo project and log in to the expo-cli with the same expo account.

> yarn global add expo-cli or npm install expo-cli -g
> expo init
> expo login
Enter fullscreen mode Exit fullscreen mode

Choose the blank (Managed workflow) template.

The app directory should look like this.

Replace the content of the current App.js file to this

import React from "react";
import { StatusBar, View, Text } from "react-native";


const App = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <View style={{ marginTop: 20 }}>
        <Text>App content</Text>
      </View>
    </>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Go back to your terminal, run yarn start or npm run start and scan the QRCode with your phone to open the application.
You can also open the app with the Expo Client mobile app, you can see your app running in the projects tab (Your phone and your computer have to be in the same network).
Expo client app projects tab

Tadaa ! Now, you should see your application running on your phone.

Now, we will adapt the code to display a list of blog posts. Open the App.js file and add a FlatList component with some fake data.

import React from "react";
import { StatusBar, View, Text, FlatList, Image } from "react-native";

const data = [
  {
    id: "dd05fda7784c5943b08b45f438aafb51",
    title: "AI Generated Human Photo Database (with API Access)",
    url: "https://redstapler.co/ai-generated-human-photo/",
    publishedAt: "2020-02-10T09:42:28.000Z",
    image:
      "https://res.cloudinary.com/daily-now/image/upload/f_auto,q_auto/v1/posts/1c8f48d32e75aa526cd4562928e46569",
    tags: ["javascript", "ai", "others"]
  },
  {
    id: "37b887d2ad3e5f79834e7555c49fec49",
    title: "Take 'this' Quiz, Understand How 'this' Works in JavaScript",
    url:
      "https://dev.to/liaowow/take-this-quiz-understand-how-this-works-in-javascript-44dj",
    publishedAt: "2020-02-09T21:28:29.000Z",
    image:
      "https://res.cloudinary.com/daily-now/image/upload/f_auto,q_auto/v1/posts/1110f8e9b4c54f5e0291c95da5171d00",

    tags: ["javascript", "beginners", "challenge"]
  }
];

const App = () => {
  const handleKeyExtractor = item => item.id.toString();

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <View style={{ marginTop: 20 }}>
        <FlatList
          data={data}
          renderItem={({ item }) => (
            <View style={{ flexDirection: "row", padding: 15 }}>
              <Image
                source={{ uri: item.image }}
                style={{ width: 80, height: 80 }}
              />
              <View style={{ flex: 1, paddingLeft: 10 }}>
                <Text
                  style={{ fontSize: 16, fontWeight: "300" }}
                  numberOfLines={2}
                  ellipsizeMode="tail"
                >
                  {item.title}
                </Text>
              </View>
            </View>
          )}
        />
      </View>
    </>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Your app will automatically reload and should now look like this

Dailynow data

Open a Dailynow tab on your browser and open the Chrome/Firefox devtool (Network tab). Refresh the page and copy the https://.../graphql?... request url to the clipboard. This request will allow us to retrieve data from the dailynow API with your personal tags.

In the App.js component, you can now fetch the data in a useEffect hook and store the response in a state.

import React, { useEffect, useState } from "react";
import { StatusBar, View, Text, FlatList, Image } from "react-native";

const App = () => {
  const handleKeyExtractor = item => item.id.toString();
  const [data, setData] = useState();

  useEffect(() => {
    (async () => {
      const response = await fetch(
        "PASTE_REQUEST_URL"
      );
      const result = await response.json();
      setData(result.data.latest);
    })();
  }, []);

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <View style={{ marginTop: 20 }}>
        <FlatList
          data={data}
          renderItem={({ item }) => (
            <View style={{ flexDirection: "row", padding: 15 }}>
              <Image
                source={{ uri: item.image }}
                style={{ width: 80, height: 80 }}
              />
              <View style={{ flex: 1, paddingLeft: 10 }}>
                <Text
                  style={{ fontSize: 16, fontWeight: "300" }}
                  numberOfLines={2}
                  ellipsizeMode="tail"
                >
                  {item.title}
                </Text>
              </View>
            </View>
          )}
        />
      </View>
    </>
  );
};

export default App;

Enter fullscreen mode Exit fullscreen mode

Link to a blog post

Install the expo-web-browser module

expo install expo-web-browser
Enter fullscreen mode Exit fullscreen mode

Add a TouchableOpacity component in the renderItem props.

import React, { useEffect, useState } from "react";
import {
  StatusBar,
  View,
  Text,
  FlatList,
  Image,
  TouchableOpacity
} from "react-native";
import * as WebBrowser from "expo-web-browser";

const App = () => {
  const handleKeyExtractor = item => item.id.toString();
  const [data, setData] = useState();

  useEffect(() => {
    (async () => {
      const response = await fetch(
        "PASTE_REQUEST_URL"
      );
      const result = await response.json();
      setData(result.data.latest);
    })();
  }, []);

  const openPost = async link => {
    await WebBrowser.openBrowserAsync(link);
  };

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <View style={{ marginTop: 20 }}>
        <FlatList
          data={data}
          renderItem={({ item }) => (
            <TouchableOpacity onPress={() => openPost(item.url)}>
              <View style={{ flexDirection: "row", padding: 15 }}>
                <Image
                  source={{ uri: item.image }}
                  style={{ width: 80, height: 80 }}
                />
                <View style={{ flex: 1, paddingLeft: 10 }}>
                  <Text
                    style={{ fontSize: 16, fontWeight: "300" }}
                    numberOfLines={2}
                    ellipsizeMode="tail"
                  >
                    {item.title}
                  </Text>
                </View>
              </View>
            </TouchableOpacity>
          )}
        />
      </View>
    </>
  );
};

export default App;

Enter fullscreen mode Exit fullscreen mode

That's it! Now take a look at the application.

A lot of features can be added very quickly to this application:

  • Refresh
  • Inifinite scroll
  • Dark mode
  • Tags settings
  • Bookmarks

I create a github repo for this tutorial that includes some of those features. Feel free to contributes :D

You can also publish your expo app with one command line expo publish. This allows you to access the app from every were. All your published apps are accessible in the expo client mobile app (Profile tab).

Thanks to the dailynow team for their awesome work!

Top comments (5)

Collapse
 
evanbacon profile image
Evan Bacon

Awesome post!!

Collapse
 
hichamelbsi profile image
ELABBASSI Hicham

Thank you Evan!

Collapse
 
joltee_gmbh profile image
JOLTEE

Great job 💪

Collapse
 
hichamelbsi profile image
ELABBASSI Hicham

Thank you Joltee!

Collapse
 
samytoubal profile image
Samy Toubal

Awesome Hicham!! Simple and easy to understand...