# How chosey handles in-app announcements with React Native

In the [chosey app](https://chosey.app), we have sometimes the need to send some information, warnings or guidance to the users in the app. One way we do this is sending in-app announcements to the users.

We use it for example to

- Announce a downtime
- Announce a new feature in the app
- Celebrate or announce contests

In the following chapter I will show you how we handle these announcements in the react native frontend.

## Give me some frontend code

The data structure of the announcements in chosey is as following:

```jsx
export interface AnnouncementInterface {
	id: string;
  title: string;
  message: string;
  active?: true;
  image?: string;
  createdAt: string;
  endDate?: string;
}
```

The backend only returns the latest announcement that is still active and where the current date is before the endDate - so we don’t have to worry about that in frontend.

```jsx
const startAnnouncementInterval = () => {
    getAnnouncement();
    const interval = setInterval(async () => {
      getAnnouncement();
    }, 60000);
    return () => {
      clearInterval(interval);
    };
  };
```

On page load we call the function `startAnnouncementInterval()` . This interval runs once if called and then every minute to check for new announcements. 

```jsx
const getAnnouncement = async () => {
	// API call to get lates announcement from server
  const announcement = await getLatestAnnouncement();   

    if (announcement?.id) {
			// the users id is part of the storage key in order to handle multiple accounts on one mobile phone
		  const announcementStorageKey = 'announcement' + me?.id;

      // load the last saved announcement from local storage
      const lastSavedAnnouncement = await loadString(announcementStorageKey);
      if (announcement?.id) {
        // if this announcement is newer than the last saved one OR there is nothing in local storage -> show and update storage
        if (
          (lastSavedAnnouncement &&
            new Date(lastSavedAnnouncement) <
              new Date(announcement.createdAt)) ||
          !lastSavedAnnouncement
        ) {
          Alert.alert(announcement.title, announcement.message);
          await saveString(announcementStorageKey, announcement.createdAt);
        }
      }
    }
  };
```

The `getAnnouncement()` function gets the latest announcement from the backend and handles the logic if the announcement shall be shown or was already seen by the user.

I used a helper class in order to handle the local storage read and write operations - the used package is the `@react-native-async-storage/async-storage` 

```jsx
import AsyncStorage from '@react-native-async-storage/async-storage';
/**
 * Loads a string from storage.
 *
 * @param key The key to fetch.
 */
export async function loadString(key: string): Promise<string | null> {
  try {
    return await AsyncStorage.getItem(key);
  } catch {
    // not sure why this would fail... even reading the RN docs I'm unclear
    return null;
  }
}

/**
 * Saves a string to storage.
 *
 * @param key The key to fetch.
 * @param value The value to store.
 */
export async function saveString(key: string, value: string): Promise<boolean> {
  try {
    await AsyncStorage.setItem(key, value);
    return true;
  } catch {
    return false;
  }
}
```

I hope this post might help you within your projects!

Happy coding!
