Link to live version: https://wafs2021.netlify.app/
The purpose of this repo is to create an SPA list of cryptocurrency. With overviews of different toplists. By volume (last 24h) or market cap. Also it should include a unique way of displaying the data. which makes it stand out from other 'crypto-list' websites.
- Getting started
- Features
- APIs used
- User & Interaction Diagram
- Design patterns used
- Checklist
- Templating Engine
- Router
- References And Sources
Clone the repository and host index.html on your (local) web server.
- Retrieve basic data from all coins (Basic Data List)
- Refine Basic Data List, Store Locally.
- Retrieve data from cache / retrieve new data; depending on timestamp
- Display market sentiment ( all +- added together)
- Show coin price allignment with market sentiment ( right column)
- Retrieve toplist by marketcap
- Template toplist by marketcap
- Homemade templating engine.
- Display user feedback (loader).
- Create Wallet feature
- Create add to Wallet functions
- Create Remove from wallet functions
- Template wallet
Cryptocompare: https://min-api.cryptocompare.com/
For this course I used the Cryptocompare API. I used fetch()
to do multiple requests.
fetch()
:
fetch = (endPoint) => {
return new Promise((resolve, reject) => {
const data = fetch(`${endPoint.url}`)
.then((res) => {
return res.json();
})
.then((data) => {
this.data = {
data: data.Data || data,
query: endPoint.query,
};
try {
this.store.stateCreate(endPoint.query, data.Data);
} catch {
console.log("listerror, refining"); // 1 list is too big to store locally right now. So I use .map() to Filter it
const refinedData = this.template.mapInitList(
data.Data,
endPoint.query
);
if (refinedData) {
this.data = {
data: refinedData,
query: endPoint.query,
};
this.store.stateCreate(endPoint.query, this.data);
console.log("data refined");
} else {
data.query = endPoint.query;
console.log("All Lists Retrieved And Stored");
}
}
resolve(this.data);
})
.catch((err) => {
console.error(err);
});
});
};
The API sends back a string which contains an object. If everything goes as planned it should look something like this:
- Javascript Modular Design Pattern (1)
- Javascript Constructor Pattern (5)
- Javascript Singleton Pattern (4)
- Interaction Diagram
- Actor Diagram
- Retrieve basic data from all coins (Basic Data List)
- Refine Basic Data List, Store Locally.
- Retrieve toplist by marketcap
- Template toplist by marketcap
- Add feature that shows the highest buy-in position possible based on buy-in capital on hands. (something like: if I spend 10.000 on Xcoin I will be at the top 100 hodlers, which is the highest I can position myself ATM) [ FEATURE REMOVED In Current Patch]
- Create Wallet feature
- Create add to Wallet functions
- Create Remove from wallet functions
- Template wallet
I couldn't have made this template engine without this article from hackernoon.com (2)
Let me explain what happens under the hood:
- I send the HTML element
(string)
and the data(object)
torender()
. - The function looks for
{{ }}
tags and uses the word inside as a reference for the value that needs to be inserted. - A
.replace
function is used to replace the word. - So if I know
data
and I needdata.name
to be rendered. I can just add {{name}} to my html.
Templating Engine Code Examples
render: (template, data) => {
// Search for anything that is surrounded by the brackets, and replace it with the name inside data.
// I.E. "{{data.FullName}}", "data = {FullName:"Bitcoin"}"
return template.replace(/{{(.*?)}}/g, (match) => {
return data[match.split(/{{|}}/).filter(Boolean)[0].trim()];
});
},
I needed to handle the routes so I've used the microlibrary routie.js
(3).
Code Examples:
Here I check for the current route then I reference to code located in this
routie({ "": this["/"], "/": this["/"], "details/:id": this["details/:id"] });
The following Code is used for the routes at the moment:
"/" = () => {
console.log("@home");
const indexPage = new Index(this.render, endPoints);
console.log(indexPage);
this.currentPage = indexPage;
};
"details/:id" = (id) => {
console.log("@details");
const detailsPage = new Details(this.render, endPoints, id);
this.currentPage = detailsPage;
};
"*" = () => {
console.log("404");
};
- https://hackernoon.com/how-to-create-new-template-engine-using-javascript-8f26313p
- https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
- https://github.com/jgallen23/routie
- https://www.dofactory.com/javascript/design-patterns/singleton
- https://blog.logrocket.com/javascript-design-pattern-214d888096a3
Special Thanks to the following people: