A Star Wars API exercise.
This exercise does not need a package.json but you will need a server in order to use AJAX.
If you don’t have it already installed, I recommend to use live-server (which can be installed with npm i -g live-server and then run from the terminal with the live-server command in the directory of your project).
Create an index.html file with:
header tag which contains:
h1 tag with the following content: “Star Wars Browser”main tag to which you add the attribute role with value mainfooter tag with the following content:
Developed with 💙 in Berlin, using the <a href="https://swapi.co/">Star Wars open API</a>.
index.js file and add the script tag in your index.html.index.js file:
var mainElement = document.querySelector('main');
//
function loadPeople(done) {
/*
fill here
---------
- make a GET request to: 'https://swapi.co/api/people/'
- call the function "done" and pass it the result of the request
*/
}
//
function renderPeople(people) {
/*
fill here
---------
For each given people (use a loop or Array.forEach())
- create a section element (with the document.createElement())
- fill the innerHTML (maybe have a look at template literals) of the section with:
- A header tag which has
- A h1 tag containing the name of the person
- A div tag which has a list of the following information:
- Birth Year
- Eye Color
- Skin Color
- Hair Color
- Height
- Mass
The list items have 2 children span
(one with the class "label" and the other with the class "value")
- Add the section element to the main element of the index.html
*/
}
// call the loadPeople with the renderPeople function as parameter
loadPeople(renderPeople);
background.gif file and save it at the root of your project.style.css (don’t forget to add the link tag):
*,
*:before,
*:after {
box-sizing:/* fill here */;
}
html {
height:/* fill here */;
}
body {
font-family:/* fill here */;
line-height:/* fill here */;
color:/* fill here */;
background-color:/* fill here */;
display:/* fill here */;
flex-direction:/* fill here */;
margin:/* fill here */;
height:/* fill here */;
background-image:/* fill here */;
background-attachment:/* fill here */;
}
a,
a:link,
a:hover,
a:visited {
color:/* fill here */;
text-decoration:/* fill here */;
}
h1,
h2,
h3 {
margin:/* fill here */;
font-weight:/* fill here */;
}
header,
footer {
color:/* fill here */;
background-color:/* fill here */;
}
body>header,
body>footer {
padding-left:/* fill here */;
padding-right:/* fill here */;
}
body>header,
body>footer {
padding-top:/* fill here */;
padding-bottom:/* fill here */;
}
body>header {
border-bottom:/* fill here */;
}
main {
flex-grow:/* fill here */;
overflow:/* fill here */;
display:/* fill here */;
flex-wrap:/* fill here */;
}
body>footer {
border-top:/* fill here */;
}
.person {
width:/* fill here */;
margin:/* fill here */;
background-color:/* fill here */;
border:/* fill here */;
border-radius:/* fill here */;
}
.person>header,
.person>div {
padding:/* fill here */;
}
.person>header {
border-bottom:/* fill here */;
}
.person ul {
padding:/* fill here */;
}
.person li {
display:/* fill here */;
padding:/* fill here */;
}
.person .label {
flex-grow:/* fill here */;
width:/* fill here */;
}
.person .gender {
color:/* fill here */;
}
.person .value {
color:/* fill here */;
}

In your index.js:
createModal which returns an element which has a class modal and has the following HTML content:
<div class="body">
<div class="controls">
<button>close</button>
</div>
<div class="content"></div>
</div>
<div class="underlay"></div>
showModal with 1 argument: contentElement and which
contentcontentElement to the modal child element with class contentopenhideModal which removes the the class open from theloadData with arguments url and done (basically, move the content of your loadPeople inside it) and replace the content of your loadPeople function with loadData('https://swapi.co/api/people/', done);loadPlanet with arguments url and doneloadData function so that you can pass a url argument (before the done argument, in the end it should look like function loadData(url, done) {/* */}).renderPeople function:
button tag above the listbuttonElement.onclick = function(){/* */} or with buttonElement.addEventListener('click', function() {/* */}))Add the following code to your style.css and complete it where necessary.
/* -------------------------------- */
.modal,
.modal>.underlay,
.modal>.body {
position: absolute;
}
.modal,
.modal>.underlay {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.modal {
height: 0;
z-index: 10;
overflow: hidden;
transition: height 300ms ease;
}
.modal.open {
height: 100%;
}
.modal>.underlay {
z-index: 10;
background-color: rgba(255, 255, 255, 0.7);
}
.modal>.body {
/* fill here */
}
.modal .controls {
/* fill here */
}
.modal .content {
/* fill here */
}

As you have seen, the “people” object that you recieve from your AJAX call is looking a bit like:
{
results: [
{name: /* ... */},
{name: /* ... */},
{name: /* ... */},
/* ... */
],
count: 87,
next: 'https://swapi.co/api/people/?page=2',
previous: null
}
In the “results” array they are only 10 records, but the total amount of people is 87. So basically, it does not give you the complete list of people but only the first 10. In order to load (and display) the next 10 people, you will need to make an other request to the “people.next” URL.
loadData which takes 2 arguments (url and done)renderPeople function add:
mainElementnav element (using document.createElement())button with:
previousloadData with the “people.previous” and renderPeoplebutton with:
nextloadData with the “people.next” and renderPeoplenav element you creatednav element to the mainElementdiv element (with a class cards) and add it to mainElementsection elements of your loop are append to the div element you just createdIn your CSS, make changes so that it looks like the previous layout and make styles for the pager buttons (so that they look a bit nicer).
index.html file, add a nav with a ul inside it.index.js:
renderersrenderPeople, add a property people to the renderers object which reference the renderPeople function.renderUnimplemented which will replace the content of the mainElement by a message like: “Sorry, this is not implemented yet.”renderMenu which takes a data argument and add links (use Object.keys(data).forEach(function(key) {/*...*/}) to iterate) in the ul of the header.
data objectrenderers object is found, it calls the loadData with the renderers[topic]renderUnimplemented function (without calling loadData)loadData) and then renders the menu.renderPlanets (similar to the renderPeople) which renders the planets information and add a reference to the renderPlanets in the renderers object like you did with renderPeople (renderers.planets = renderPlanets;). You may need to make some changes to your CSS.You probably have a lot of code which looks similar accross your functions. Try to clean that up. :)
Add a visual indication of the loading (between the click on the menu link until the content renders).
Using the hashchange.
Animate the opening crawl of the films in a star wars fashion.