---
id: 69b868127999e97f1903f8e1
title: Build a Flashcard Quiz App
challengeType: 25
dashedName: lab-flashcard-quiz-app
demoType: onClick
saveSubmissionToDB: true
---
# --description--
In this lab, you will create an app that displays and stores flashcard data that can
be retrieved later.
**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
**User Stories:**
1) You should have an HTML element with an id of `flashcard`.
2) You should have an interface called `FlashCard`.
3) The `FlashCard` interface should contain the following properties `questionText` and `questionAnswer` both of type `string`.
4) You should have a collection of `FlashCard` elements called `currentCards`.
5) When the `#flashcard` element is clicked, the card should have the `flipped` class.
6) You should have an element with an id of `delete-btn`.
7) When the `#delete-btn` element is clicked, it should remove current card and display the previous card data.
8) You should create an entry form with an id of `entry-form` to be able to add more flashcards to the `currentCards` collection on submit.
9) The two elements inside of the form should have an id of `front-text` and `back-text` respectively.
10) You should create and call an `InvalidUserInputError` when either the question text or question answer is empty in the entry form.
# --hints--
You should have an HTML element with an id of `flashcard`.
```js
const element = document.querySelector("#flashcard");
assert.exists(element);
```
You should have a `FlashCard` interface.
```js
const explorer = await __helpers.Explorer(code);
console.log(explorer.interfaces.FlashCard)
assert.exists(explorer.interfaces.FlashCard);
```
The `FlashCard` interface should have a `questionText` property of type `string`.
```js
const explorer = await __helpers.Explorer(code);
const { FlashCard } = explorer.interfaces;
assert.isTrue(FlashCard.hasTypeProps([{ name: "questionText", type: "string" }]));
```
The `FlashCard` interface should have a `questionAnswer` property of type `string`.
```js
const explorer = await __helpers.Explorer(code);
const { FlashCard } = explorer.interfaces;
assert.isTrue(FlashCard.hasTypeProps([{ name: "questionAnswer", type: "string" }]));
```
You should have a collection of `FlashCard` elements called `currentCards` with the type `FlashCard[]`.
```js
const explorer = await __helpers.Explorer(code);
assert.exists(explorer.variables.currentCards);
assert.isTrue(explorer.variables.currentCards.annotation.matches('FlashCard[]'));
```
When the `#flashcard` element is first clicked, the element should receive the `flipped` class.
```js
const element = document.querySelector("#flashcard");
element.click();
assert.isTrue(element.classList.contains("flipped"));
```
You should have an element with an id of `delete-btn`.
```js
const element = document.querySelector("#flashcard");
assert.exists(element);
```
When the `delete-btn` is clicked, a flashcard element should be removed from the `currentCards` collection.
```js
const entryForm = document.querySelector("#entry-form");
const frontText = document.querySelector("#front-text");
const backText = document.querySelector("#back-text");
const deleteBtn = document.querySelector("#delete-btn");
const flashCard = document.querySelector("#flashcard");
const submitBtn = entryForm.querySelector("button[type='submit']");
frontText.value = "Test question";
backText.value = "Test answer";
submitBtn.click();
frontText.value = "Test question 2";
backText.value = "Test answer 2";
submitBtn.click();
deleteBtn.click();
assert.notInclude(flashCard.textContent, "Test question 2");
```
When the `delete-btn` is clicked, the previous flashcard data should be displayed.
```js
const entryForm = document.querySelector("#entry-form");
const frontText = document.querySelector("#front-text");
const backText = document.querySelector("#back-text");
const deleteBtn = document.querySelector("#delete-btn");
const flashCard = document.querySelector("#flashcard");
const submitBtn = entryForm.querySelector("button[type='submit']");
frontText.value = "Test Front 1";
backText.value = "Test Back 1";
submitBtn.click();
frontText.value = "Test Front 2";
backText.value = "Test Back 2";
submitBtn.click();
deleteBtn.click();
assert.include(flashCard.textContent, "Test Front 1");
assert.notInclude(flashCard.textContent, "Test Front 2");
```
You should create an entry form with an id of `entry-form`.
```js
const element = document.querySelector("#entry-form");
assert.exists(element);
```
You should have two `textarea` elements of ids `front-text` and `back-text` respectively inside the form.
```js
const entryForm = document.querySelector("#entry-form");
const frontText = entryForm.querySelector("#front-text");
const backText = entryForm.querySelector("#back-text");
assert.exists(frontText);
assert.exists(backText);
assert.equal(frontText.tagName.toLowerCase(), "textarea");
assert.equal(backText.tagName.toLowerCase(), "textarea");
```
An `InvalidUserInputError` should be thrown when either the question text or question answer is empty in the entry form.
```js
const entryForm = document.querySelector("#entry-form");
const frontText = document.querySelector("#front-text");
const backText = document.querySelector("#back-text");
const submitBtn = entryForm.querySelector("button[type='submit']");
const lengthBefore = currentCards.length;
frontText.value = "";
backText.value = "Some answer";
submitBtn.click();
assert.strictEqual(currentCards.length, lengthBefore);
frontText.value = "Some question";
backText.value = "";
submitBtn.click();
assert.strictEqual(currentCards.length, lengthBefore);
```
# --seed--
## --seed-contents--
```html
```
```css
```
```ts
```
# --solutions--
```html