DEV Community

Cover image for Engage Your Audience with Interactive Polls and Quizzes - A Step-by-Step Guide
John Selvinraj for 100ms Inc.

Posted on

Engage Your Audience with Interactive Polls and Quizzes - A Step-by-Step Guide

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:

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

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.
  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.

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:

npm create vite@latest my-polls-app -- --template react
Enter fullscreen mode Exit fullscreen mode

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.

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.

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:

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;
Enter fullscreen mode Exit fullscreen mode

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:

.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);
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

<!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>
Enter fullscreen mode Exit fullscreen mode

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

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;
Enter fullscreen mode Exit fullscreen mode

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.

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);
  };
Enter fullscreen mode Exit fullscreen mode

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.

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:

import { useState } from "react";
import { Button } from "@100mslive/roomkit-react";
Enter fullscreen mode Exit fullscreen mode

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

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

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

const hidePollFormHandler = () => {
    setPollFormIsShownn(false);
    };
Enter fullscreen mode Exit fullscreen mode

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

{pollFormIsShown && <PollForm onClose={hidePollFormHandler} />}
<Button onClick={showPollFormHandler}>Create Poll</Button>
Enter fullscreen mode Exit fullscreen mode

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.

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";
Enter fullscreen mode Exit fullscreen mode

Initialise notifications and localPeerID to use them as follows:

const notification = useHMSNotifications();
const localPeerID = useHMSStore(selectLocalPeerID);
Enter fullscreen mode Exit fullscreen mode

Using useEffect we check for any new notifications. Add the following code to App.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]);
Enter fullscreen mode Exit fullscreen mode

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:

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

const showPollModalHandler = () => {
    setPollModalIsShown(true);
  };
Enter fullscreen mode Exit fullscreen mode

In the return, add a ViewPoll component as follows:

{pollModalIsShown && (
            <ViewPoll pollNotificationData={pollNotificationData} />
          )}
Enter fullscreen mode Exit fullscreen mode

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.

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;
Enter fullscreen mode Exit fullscreen mode

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

  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!`);
  };
Enter fullscreen mode Exit fullscreen mode

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!

The code for this project is available on GitHub here.

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.
  • Add Polls to your Android or iOS app.
  • Join our discord server in case of any doubts and to help us build it further.

Top comments (0)