Engage Your Audience with Interactive Polls and Quizzes - A Step-by-Step Guide
Published: 2023-10-16 05:41:28

One of the most requested features from our customers was the ability to create polls and quizzes. We are excited to announce that this feature is now available! 

Polls are a great way to get feedback from your audience, learn more about their interests, and engage them in a two-way conversation. Want to get feedback on the session? Create a poll. Let your audience rate the session as good or bad.

The questions can be made single-choice or multiple-choice. The feedback example discussed above would be a single-choice question. Whereas if you want to conduct market research on say what social media platform everyone in the room uses. That would require a multiple-choice question.

Needless to say, polls can enhance audience engagement and add interactivity to virtual meetings, conferences, or live streams. They also enable you to collect well-organized data by posing direct questions.

Create polls in 100ms rooms in the following way:

<video width="1280" height="720" controls> <source src="https://storage.googleapis.com/100ms-cms-qa/cms/Polls_demo_creating_a_poll_using_web_app_0ab6eea062/Polls_demo_creating_a_poll_using_web_app_0ab6eea062.mp4?updated_at=2023-09-05T09:04:36.400Z" type="video/mp4"> </video>

Once a poll is created and launched by a peer, other peers with permission to view the polls can interact with it. 

<video width="1280" height="720" controls> <source src="https://storage.googleapis.com/100ms-cms-qa/cms/Casting_vote_demo_6e3e936feb/Casting_vote_demo_6e3e936feb.mp4?updated_at=2023-09-05T09:04:31.131Z" type="video/mp4"> </video>

Moreover, the Polls can be extended to create quizzes as well. 

To delve a bit deeper, quizzes operate on a similar principle to polls, albeit with a twist. 

In the world of quizzes, questions come with designated correct and incorrect answers, adding an element of assessment and knowledge evaluation to the interactive experience. It can be used to craft educational assessments, test comprehension, and promote active learning through engagement.

Let’s get into the mix of building things using 100ms Polls and Quizzes.

## How to enable polls and quizzes for your rooms on the 100ms dashboard?

1. **Access the 100ms Dashboard**: Begin by visiting the [100ms dashboard](https://dashboard.100ms.live/dashboard).
2. **Choose or Create a Template**: Select the template where you want to enable polls and quizzes. Alternatively, create a new template by clicking the 'Create Template' button.
3. **Access Template Configuration**: Click on the 'Configure' button within your chosen template.
4. **Assign Poll Creation Privileges**: Select which role(s) should have the ability to create polls.
5. **Set Permissions**: In the 'Permissions' section, activate the following toggles:
    ◦ 'Create polls and quizzes'
    ◦ 'Read polls and quizzes'
6. **Exclusive Interaction**: If certain role(s) should only participate in polls without creating them, enable only the 'Read polls and quizzes' toggle for those roles.

<video width="1280" height="720" controls> <source src="https://storage.googleapis.com/100ms-cms-qa/cms/enable_polls_and_quizes_b6b1901149/enable_polls_and_quizes_b6b1901149.mp4?updated_at=2023-09-13T06:55:02.593Z" type="video/mp4"> </video>

## How to add Polls to React sample app?

Let’s add polls to a React sample app to see how easy it is.

Start by creating a new React project (I’ll use Vite to create one) by running the following command:

```jsx
npm create vite@latest my-polls-app -- --template react
```

This would create a new project folder `my-polls-app` in your desired directory with React configured in it.

Now, to quickly add the 100ms React SDK and enable live audio-video in our app, we will follow the React Quickstart Guide [here](https://www.100ms.live/docs/javascript/v2/quickstart/react-quickstart).

Once done, we should have a React project with audio-video calling using 100ms set up.

> The complete React Quickstart Guide code can be found [here](https://codesandbox.io/s/github/100mslive/100ms-examples/tree/main/web/react-quickstart). 

Create a new folder in the `src` directory called `Components` and add two subfolders `Poll` and `UI` to it. These folders would have the code for the necessary UI and Poll components.

We start by creating a `Modal.jsx` file inside the `UI` folder. This file would have the following code: 

```jsx
import { Fragment } from "react";
import ReactDOM from "react-dom";
import classes from "./Modal.module.css";

const Backdrop = (props) => {
  return <div className={classes.backdrop} onClick={props.onClose}></div>;
};

const ModalOverlay = (props) => {
  return (
    <div className={classes.modal}>
      <div className={classes.content}>{props.children}</div>
    </div>
  );
};

const portalElement = document.getElementById("overlays");

const Modal = (props) => {
  return (
    <Fragment>
      {ReactDOM.createPortal(
        <Backdrop onClose={props.onClose} />,
        portalElement
      )}
      {ReactDOM.createPortal(
        <ModalOverlay>{props.children}</ModalOverlay>,
        portalElement
      )}
    </Fragment>
  );
};
export default Modal;
```

 The Modal component is made up of the `Backdrop` and `ModalOverlay` . The `ModalOverlay` would provide a white background to lay the children on passed to it using props.

You’d notice we have imported a css file but haven’t defined it yet. So, inside the same `UI` folder create a new file called `Modal.module.css` and add the following to it: 

```css
.backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 20;
  background-color: rgba(0, 0, 0, 0.75);
}

.modal {
  position: fixed;
  top: 20vh;
  left: 5%;
  width: 90%;
  background-color: #546e7a;
  padding: 1rem;
  border-radius: 14px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  z-index: 30;
  animation: slide-down 300ms ease-out forwards;
}

@media (min-width: 768px) {
  .modal {
    width: 40rem;
    left: calc(50% - 20rem);
  }
}

@keyframes slide-down {
  from {
    opacity: 0;
    transform: translateY(-3rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
```

Lastly, to complete our Modal, we also need to modify the `index.html` in the root of the project directory to add another `div` with `id="overlays"` before the root `div` as below:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>100ms Polls Demo</title>
  </head>
  <body>
    <div id="overlays"></div>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>
```

Now, we will work on a form to create a poll. Start by creating a form as follows:

```jsx
import Modal from ".././UI/Modal";
import { Button } from "@100mslive/roomkit-react";
import { useState } from "react";
import { useHMSActions } from "@100mslive/react-sdk";
import "../../styles.css";

const PollForm = (props) => {
	const hmsActions = useHMSActions();
  const [inputs, setInputs] = useState({});

  return (
    <Modal onClose={props.onClose}>
      <form onSubmit={handleSubmit}>
        <label>
          Enter a Name for the Poll:
          <div className="input-container">
            <input
              type="text"
              name="name"
              value={inputs.name || ""}
              onChange={handleChange}
            />
          </div>
        </label>
        <label>
          Enter a question for the Poll:
          <div className="input-container">
            <input
              type="text"
              name="text"
              value={inputs.text || ""}
              onChange={handleChange}
            />
          </div>
        </label>
        <label>
          Enter the First Value:
          <div className="input-container">
            <input
              type="text"
              name="first"
              value={inputs.first || ""}
              onChange={handleChange}
            />
          </div>
        </label>
        <label>
          Enter the Second Value:
          <div className="input-container">
            <input
              type="text"
              name="second"
              value={inputs.second || ""}
              onChange={handleChange}
            />
          </div>
        </label>
        <input type="submit" />
      </form>
    </Modal>
  );
};
export default PollForm;
```

You’ll notice we are having the user input a name for the poll, a question and two options to choose from. To manage changes in values and successfully submit the form, we add the following functions.

```jsx
const handleChange = (event) => {
    const name = event.target.name;
    const value = event.target.value;
    setInputs((values) => ({ ...values, [name]: value }));
  };

  const handleSubmit = async (event) => {
    event.preventDefault();
    const id = Date.now().toString();
    await hmsActions.interactivityCenter
      .createPoll({
        id,
        title: inputs.name,
        type: "poll",
        rolesThatCanViewResponses: ["host"],
      })
      .then(() => handleCreate(id))
      .catch((err) => console.log(err.message));
  };

const handleCreate = async (id) => {
    console.log("POLL CREATED with ${id}");
    await hmsActions.interactivityCenter.addQuestionsToPoll(id, [
      {
        text: inputs.text,
        type: "single-choice",
        options: [
          {
            text: inputs.first,
            isCorrectAnswer: false,
          },
          {
            text: inputs.second,
            isCorrectAnswer: false,
          },
        ],
        skippable: true,
      },
    ]);
    await hmsActions.interactivityCenter.startPoll(id);
  };
```

The `handleChange` takes any changes in the text input fields and sets the `inputs` variable accordingly. On form submission, the `handleSubmit` is called which uses the `useHMSActions` hook to create a new poll.

Once a poll is created, `handleCreate` is run to `addQuestionsToPoll` and also `startPoll` using the same `hmsActions`.

The complete `PollForm.jsx` file would then look as [this](https://github.com/adityathakurxd/live-audio-video/blob/main/src/Components/Poll/PollForm.jsx).

Next, we return to our `App.jsx` file to display the `PollForm` when the user clicks on a `Create Poll` button.

Start by importing the following:

```jsx
import { useState } from "react";
import { Button } from "@100mslive/roomkit-react";
```

We will use `useState` to manage the state of the `PollForm` if we need to show or hide it.

```jsx
const [pollFormIsShown, setPollFormIsShownn] = useState(false);

const showPollFormHandler = () => {
    setPollFormIsShownn(true);
  };

const hidePollFormHandler = () => {
    setPollFormIsShownn(false);
	};
```

Add the `PollForm` component and a button with `showPollFormHandler` being passed to it as below:

```jsx
{pollFormIsShown && <PollForm onClose={hidePollFormHandler} />}
<Button onClick={showPollFormHandler}>Create Poll</Button>
```

Once this is done, we should be able to toggle and view the `PollForm` and dismiss it by clicking the backdrop area. We should also be able to create and start a poll with the name, question and choices entered by the user.

Let us now work to show the Poll to any other users using our app.

We can use the `useHMSNotifications` hook to be notified when a new poll is started. We will use this to show a toast using `react-toastify` when a new poll has begun.

Add the package by running: `npm install --save react-toastify`

Add the following imports to the `App.jsx` file.

```jsx
import {
  selectIsConnectedToRoom,
  selectLocalPeerID,
  useHMSActions,
  HMSNotificationTypes,
  useHMSStore,
  useHMSNotifications,
} from "@100mslive/react-sdk";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { useEffect, useState } from "react";
```

 Initialise notifications and localPeerID to use them as follows:

```jsx
const notification = useHMSNotifications();
const localPeerID = useHMSStore(selectLocalPeerID);
```

Using `useEffect` we check for any new notifications. Add the following code to `App.jsx` 

```jsx
const [pollNotificationData, setPollNotificationData] = useState();

useEffect(() => {
    if (!notification) {
      return;
    }
    switch (notification.type) {
      case HMSNotificationTypes.POLL_STARTED:
        if (notification.data.startedBy !== localPeerID) {
          console.log("NOTIFICATION RECEIVED");
          console.log(notification.data);
          setPollNotificationData(notification.data);
          toast(`A new Poll is available: ${notification.data.title}!`);
        }
        break;
      default:
        break;
    }
  }, [notification]);
```

Lastly, add `<ToastContainer />` to the return of `App.jsx` to view a toast when some other remote user creates a new poll. Notice how we have added a check to not show toast to the local peer itself.

Now, we want to be able to cast our vote on the created poll. To do that we again start by showing a modal with the poll data for the users to vote. To the `App.jsx` add the following:

```jsx
const [pollModalIsShown, setPollModalIsShown] = useState(false);

const showPollModalHandler = () => {
    setPollModalIsShown(true);
  };
```

In the return, add a `ViewPoll` component as follows:

```jsx
{pollModalIsShown && (
            <ViewPoll pollNotificationData={pollNotificationData} />
          )}
```

Let us now work on this component. Create a new file called `ViewPoll.jsx` inside the `Poll` folder in the `Components` directory. First, create a basic form layout with radio buttons using the same `Modal` component we had created earlier.

```jsx
import Modal from "../UI/Modal";
import { useState } from "react";
import { Button } from "@100mslive/roomkit-react";
import { useHMSActions } from "@100mslive/react-sdk";
import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

const ViewPoll = (props) => {

  return (
    <Modal onClose={props.onClose}>
      <h1>Poll: {props.pollNotificationData.title}</h1>

      <h3>{props.pollNotificationData.questions[0].text}</h3>

      <form onSubmit={handleSubmit}>
        <div className="radio">
          <label>
            <input
              type="radio"
              value={props.pollNotificationData.questions[0].options[0].index}
              checked={Number(selectedOptionIndex) === 1}
              onChange={handleChange}
            />
            {props.pollNotificationData.questions[0].options[0].text}
          </label>
        </div>

        <div className="radio">
          <label>
            <input
              type="radio"
              value={props.pollNotificationData.questions[0].options[1].index}
              checked={Number(selectedOptionIndex) === 2}
              onChange={handleChange}
            />
            {props.pollNotificationData.questions[0].options[1].text}
          </label>
        </div>

        <br />
        <Button type="submit">Submit</Button>
      </form>
    </Modal>
  );
};
export default ViewPoll;
```

And, lastly, add functions to handle changes made in the form and submission as follows:

```jsx
  const actions = useHMSActions();
  const [selectedOptionIndex, setSelectedOptionIndex] = useState();

  function handleChange(event) {
    setSelectedOptionIndex(event.target.value);
  }

  const handleSubmit = async (event) => {
    event.preventDefault();

    await actions.interactivityCenter.addResponsesToPoll(
      props.pollNotificationData.id,
      [
        {
          questionIndex: props.pollNotificationData.questions[0].index,
          option: Number(selectedOptionIndex),
        },
      ]
    );

    toast(`Vote done!`);
  };
```

Notice how we are using the `useHMSActions` hook to `addResponsesToPoll` by passing the poll id obtained from the data passed in as props. 

With this done, our application should now be ready to test!

<video width="1280" height="720" controls> <source src="https://storage.googleapis.com/100ms-cms-qa/cms/Polls_in_action_on_React_sample_124f7fca5f/Polls_in_action_on_React_sample_124f7fca5f.mp4?updated_at=2023-09-05T09:51:50.410Z" type="video/mp4"> </video>

> The code for this project is available on GitHub [here](https://github.com/adityathakurxd/live-audio-video).

The React app that we’ve built here allows you to create the poll, add single-choice questions as well, and start it for remote users. Using the 100ms SDK, we can also create multiple-choice polls and quizzes as mentioned in the article before.

With the ability to curate customized polls, incorporate thought-provoking questions, and initiate real-time participation from remote users through the React app, a world of engaging possibilities opens up. The dynamic fusion of technology and user interaction empowers developers to not only enhance the virtual experience but also extract valuable data and insights.

Ready to dive in? To grasp the full extent of what's achievable and delve into practical steps, look at our comprehensive documentation.

- Get started on the web [here](https://www.100ms.live/docs/javascript/v2/how-to-guides/build-interactive-features/polls).
- Add Polls to your [Android](https://www.100ms.live/docs/android/v2/how-to-guides/interact-with-room/room/polls) or [iOS](https://www.100ms.live/docs/ios/v2/how-to-guides/interact-with-room/room/polls) app.
- Join our [discord server](https://discord.com/invite/kGdmszyzq2) in case of any doubts and to help us build it further.