Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Herkansing #14

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 159 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,164 @@
The course repo for 'Web App From Scratch'

## Advantages and disadvantages of JavaScript libraries/frameworks
...
![Framework Joke][coverlibrarie]

## Advantages and disadvantages of client-side single page web apps
...
_Framework:_
JavaScript libraries are collections of pre-written JavaScript which in turn all perform certain separate functions. They can be used for the development of other JavaScript without the developer having to write his own JavaScript for the functions the library provides him with.

## Best practices
...
_Libraries:_
A library is an unopinionated piece of software which implements a certain functionality with a defined API a developer can call from their application.

**Pro’s:**
- Efficiency — projects that used to take months and hundreds of lines of code now can be achieved much faster with well-structured prebuilt patterns and functions.
- Usage — Super easy to use.
- Safety — top JavaScript frameworks have firm security arrangements and are supported by large communities where members and users also act as testers.
- Cost — most frameworks are open source and free. Since they help programmers to build custom solutions faster, the ultimate price for web app will be lower.
- Community — An excellent framework has a well-established community as well as support documentation in order, thereby allowing you to refer to the docs or seek help from members of the community if you run into a problem or encounter a bug.


**Cons:**
- Memory — owing to a large set of powerful features, most frameworks tend to be bulky regarding functions and code base. It takes up a lot of memory.
- Learning — You don't learn the deep-down JavaScript code because you're using shortcut functions within the framework.
- Lifetime — Frameworks/libraries die all the time. It must be we-written sooner or later.
- Loading — The loading times are way slower than Vanilla JS.
- Browser — Quite a few frameworks rely on browser detection.
- Editing — The framework’s core behavior can’t be modified, meaning that when you use a framework, you are forced to respect its limits and work the way it is required.
- Bugs — a bug within a library can be difficult to locate and fix.

![Frameworkcons][coverframeworkcons]

[coverlibrarie]: previewlibrarie.jpg
[coverframeworkcons]: frameworkcons.png

**Sources:**
* https://hashnode.com/post/vanilla-javascript-vs-frameworks-and-libraries-finding-a-good-balance-civ1zfus90pphdc53q8vtakz5
* https://hackernoon.com/5-best-javascript-frameworks-in-2017-7a63b3870282
* https://www.khanacademy.org/computing/computer-programming/html-css-js/using-js-libraries-in-your-webpage/a/the-world-of-js-libraries
* https://www.giftofspeed.com/dont-use-javascript-libraries/
* https://davidwalsh.name/6-reasons-to-use-javascript-libraries-frameworks
* https://www.noupe.com/development/javascript-frameworks-94897.html
* https://1stwebdesigner.com/web-frameworks/

## Best practices - Movie App

for the assignment we had to make a single page web app. The subject I chose was movies. The plan I came up with was making 2 pages. A start page that explains what my website does. A second page that shows the movies from the API I'm using (the New York Times Movie APA). And a detail page that shows the individual movie with plot summary and poster from the movie.

### How was my progress?
It was really difficult to start. Lucky for me, the teacher helped me and other students with a basic set up. This helped me understand the basic structure. From here I started adding more functionalities. The first one was making sure the the route will work. It has to be all on one page. I made everything in sections. The sections must not be visible, unless the section is active. I did this by making a loop that will check every section and is looking for the class that must set is.

```javascript
for (var i = 0; i < document.querySelectorAll("section").length; i++) {
document.querySelectorAll("section")[i].classList.add("none")
}
if (document.querySelector(route)) {
document.querySelector(route).classList.remove("none")
} else {
return
}
```

After the loop the next task was to use a Routie to correctly. The Routie will handle the routing of the page. This was fairly easy to do. There was a lot of documentation on it online. My basic Routie is:

```javascript
var routes = {
init() {
routie({
'start': function() {
console.log('test')
sections.toggle(window.location.hash)
},
'movies': function() {
console.log('start')
api.call('https://api.nytimes.com/svc/movies/v2/reviews/search.json?api-key=3d8eafd7eaf04aa6a1493eaa050714a7').then(function(data){
sections.render(data.results.sort((a, b) => a.display_title.localeCompare(b.display_title)))
})
sections.toggle(window.location.hash)
}
```

In my routie I also call for the Api (the New York Times ). The API Key is also activated when this happens. I also sort the data from the API. This will give a more pleasant use for the user. After the API has been succesfully called, it was time for the data to display into my HTML. This was done by using a templating tool. Transparancy. This will collect the data from the API and it will let me place it. For the transparancy I used a map function. This will let collect the data and place it into a by my giving name.

```javascript
var sections = {
render: function(data) {

let dataFilm = data.map(function(i) { // Map function thanks to Keving Wang and Oy
return {
display_title: i.display_title.replace(/ /g, "_")
}
});

let movies = {
display_title: {
href: function(params) {
return `/#movies/${this.display_title}`
},
headline: {
class: function(params) {
return this.headline
}
}
}
```

This was also really usefull for my detail page. This page must show the title, plot and a poster from the movie. Unfortunately, my API didn't had that much information. This was really dissapointing, but more about that later. In the let datafilm I bind the data with the by my chosen name. I also replace white space with a underscore. This must be done so the URL will be displayed correctly.

### A second API?
Because my first API didn't had much unformation, I searched for a second API. The one I found was Omdbapi. This one had more (usefull) info. I called the data from this API in my routie. When the ID (title from the movie) is being used, the API will set that ID in his search. The page that will be shown is the information from the movie. How I used it was doing the following:

```javascript
'movies/?:name': function(name) {
console.log(name)
sections.toggle(name)
document.getElementById('moviemain').classList.remove('none');
var names = name

fetch(`http://www.omdbapi.com/?t=${names}&apikey=b0b13f21`)
.then( res => {
return res.json()
} )
.then( res => {
console.log( res )
var directives = {
image: {
src: function() {
return `${this.Poster}`
}
}
}
Transparency.render(document.querySelector('#moviemain'), res, directives);
} )
```

I had trouble with this, so I asked my good friend Mo to help me out with this. We did it with ES6, because this was the most easy and fastest way to produce it. The api will be fetched and I gather the plot info and the poster. With the information gathered I splitted the Javascript into multiple modules. This is easier to find your code and reads better. The next thing I did was thinking about what will happen in the case of no Wi Fi. There would be no information to display. I solved this by using a localstorage. This will save the data from the API for use in a offline environment. I did it by doing:

```javascript
var localStorageData = {
setItem: function(data){
localStorage.setItem('filmdata', JSON.stringify(data))
},
getItem: function(){
if (JSON.parse(localStorage.getItem('filmdata')) !=null ) {
console.log('filmdata bestaat')
this.use()
}
else{
console.log('geen filmdata')
}
},
use: function(){
var savedata = JSON.parse(localStorage.getItem('filmdata'))
sections.render(savedata)
}
}
```

This will collect the data and set the data in a object. If the data is available it will be used.
After this was done all I did was clean the code.

### What am I most proud of?
Actually coming this far is what I'm most proud of. It was really difficult, but I didn't give up. I asked for a lot of help and I dived into the code.

### What do I find most disappointing
What I did find most disappointing was my lack of skill. I had to ask for help A LOT of times and I felt bad about it. I need to improve my own skill.
39 changes: 39 additions & 0 deletions app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="static/css/styles.css">
<title>Route</title>
</head>
<body>
<section id="start">
<h1>Start</h1>
<p>In my first route project you can see R rated movies and the description of the chosen movie.</p>
</section>
<section id="movies" class="none">
<h1>Movie reviews</h1>
<ul id="movielist">
<li><a class="display_title" data-bind="film_id"></a></li>
</ul>
</section>
<div id="loader"></div>
<section id="moviemain" class="none">

<h1 data-bind='Title'></h1>
<img data-bind='image' alt="">
<p data-bind='Plot'></p>
</section>
<footer>
<nav>
<ul>
<a href="#start"><li>Start</li></a>
<a href="#movies"><li>movies</li></a>
</ul>
</nav>
</footer>
<script src="static/js/transparency.min.js"></script>
<script src="static/js/routie.js"></script>
<script type="module" src="static/js/app.js"></script>
</body>
</html>
62 changes: 62 additions & 0 deletions app/static/css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

body{
font-family: "Open Sans";
text-align: center;
color: #81b3d2;
background-color: #151837
}

ul{
list-style-type: none;
padding: 0;
}

a{
font-weight: 800;
text-decoration: none;
color: #81b3d2;
}

.none{
display: none;
}

ul li{
margin-top: 0.2em;
}


footer{
bottom: 0;
left: 0;
position: absolute;
width: 100%;
background-color: #FFFFFF;
}

footer a{
font-weight: 400;
}

footer ul{
display: flex;
justify-content: space-around;
padding: 0;
list-style-type: none;
}

footer ul a{
text-decoration: none;
color: black;
}

#loader {
margin: auto;
border: 0.5em solid #f3f3f3;
border-radius: 50%;
border-top: 0.5em solid #e92f5b;
width: 5em;
height: 5em;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
}
45 changes: 45 additions & 0 deletions app/static/js/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

var loader = {
hide: function(){
var loader = document.getElementById('loader');
loader.classList.add('none')
},
show: function(){
var loader = document.getElementById('loader');
loader.classList.remove('none');
}
}

var api = {

call: function (apiURL) {
loader.show()
var promise = new Promise(function (resolve, reject) {
var request = new XMLHttpRequest();
request.open('GET', apiURL, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var data = JSON.parse(request.responseText);
resolve(data)
loader.hide()
} else {
console.log("yo")
// We reached our target server, but it returned an error

}
};

request.onerror = function() {
// There was a connection error of some sort
document.body.innerHTML += 'Could not get the data. Are you connected to the internet?'
reject('Could not get data from ' + apiURL + ', are you connected to the internet?')
};

request.send();
})
return promise
}
}

export default api
23 changes: 23 additions & 0 deletions app/static/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// import api from './api.js'
import routes from './routes.js'

console.log('global scope');
//create local scope
(function() {
var settings = {
sections: document.querySelectorAll('sections')
}
console.log('local scope');
//initialize application
var app = {
// is een method wat je kan uitvoeren
init: function() {
console.log('app initialised')
routes.init()
}
}

//start the application
app.init()

})()
22 changes: 22 additions & 0 deletions app/static/js/localstorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import sections from './render.js'
var localStorageData = {
setItem: function(data){
localStorage.setItem('filmdata', JSON.stringify(data))
},
getItem: function(){
if (JSON.parse(localStorage.getItem('filmdata')) !=null ) {
console.log('filmdata bestaat')
this.use()
}
else{
console.log('geen filmdata')
// document.body.innerHTML += "Hallo"
}
},
use: function(){
var savedata = JSON.parse(localStorage.getItem('filmdata'))
sections.render(savedata)
}
}

export default localStorageData
Loading