Skip to content
Closed
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
59 changes: 59 additions & 0 deletions canonicals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
var APP = APP || {};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're using modules already, why not just go with a solution like requirejs or commonjs and be done with it? (Not critical though)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered requirejs or browserify, but I think the requirejs syntax is extremely bloated and I don't like it. Browserify is much nicer IMO but would need a build-step so I figured I'd just go bare-bone.

Maybe just scrap the modules entirely and put everything in a single file is just as good? Would save 2 requests as well.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm for babel :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to dig into some ES6 but I think having a build step makes it way more cumbersome to add new question ids to the canonical list. Being able to make a PR with a new question directly through github's web interface increases the chance it will be done dramatically. With a build step PRs also has to include re-transpiled source code.

(function(app) {

var canonicals = {

closures: [750486],
asynchronous: [14220321],
inheritance: [11072556, 7486825]

};

var ids = Object.keys(canonicals).map(function(category) {
return canonicals[category].join(';');
});

app.xhr.fetch(ids.join(';')).then(function success(questions) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use reduce instead of doing 2 maps

var canonicalQuestions = questions.items.reduce(function(questionMap, soQuestion) {
return Object.keys(canonicals).reduce(function(questionArr, category) {
questionMap[category] = questionMap[category] || [];
if (containsQuestionId(canonicals[category], soQuestion.question_id)) {
questionMap[category].push(soQuestion);
}
return questionMap;
}, [])
return questionMap;
}, {});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks terrible, there's a better way, right? There has to be. I feel like I've completely missed the point of using reduce.

document.body.appendChild(app.dom.h1({}, [], 'List of canonicals'));

var sections = Object.keys(canonicalQuestions).map(function(category) {
return app.dom.section({ class: 'category' }, [
app.dom.h2({}, [], category),
app.dom.ul({}, canonicalQuestions[category].map(function(question) {
return app.dom.li({}, [createQuestionElement(question)]);
}))
]);
});

document.body.appendChild(app.dom.div({ class: 'canonicals' }, sections));
document.body.appendChild(app.dom.div({}, [], 'Number of remaining API calls before meltdown: ' + questions.quota_remaining));
}, function error(reasons) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use catch

document.body.appendChild(app.dom.div({}, [], 'Something went pearshaped because ' + reasons));
});

function containsQuestionId(arr, id) {
return arr.some(function(e) {
return e === id;
});
}

function createQuestionElement(question) {
return app.dom.div({}, [
app.dom.span({ class: 'score' }, [], question.score),
app.dom.a({ href: question.link, target: '_blank' }, [], question.title),
app.dom.div({ class: 'tags' }, question.tags.map(function(tag) { return app.dom.span({}, [], tag) }))
]);
}

}(APP));
25 changes: 25 additions & 0 deletions dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var APP = APP || {};
(function(app) {

function element(name) {
return function(attrObj, children, textContent) {
var e = document.createElement(name);
Object.keys(attrObj || {}).forEach(function(prop) {
e.setAttribute(prop, attrObj[prop]);
});
(children || []).forEach(function(child) {
e.appendChild(child);
});
if (textContent) {
e.innerHTML = textContent;
}
return e;
}
}

app.dom = {};
['h1', 'h2', 'section', 'div', 'ul', 'li', 'span', 'a'].forEach(function(name) {
app.dom[name] = element(name);
});

}(APP));
10 changes: 6 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World - JavaScript room</title>
<title>JavaScript room</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>

Hello World!

<script src="https://cdn.jsdelivr.net/bluebird/latest/bluebird.min.js"></script>
<script src="xhr.js"></script>
<script src="dom.js"></script>
<script src="canonicals.js"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.canonicals {
margin-left: 20px;
}

.canonicals ul {
list-style-type: none;
}

.canonicals li {
padding: 20px 0;
border-bottom: thin solid gray;
}

.canonicals .score {
width: 50px;
background-color: lightgray;
padding: 10px;
margin: 5px;
}

.canonicals .tags {
margin-top: 20px;
}

.canonicals .tags span {
padding: 5px;
background-color: lightgray;
margin: 0 5px 0 5px;
}
29 changes: 29 additions & 0 deletions xhr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var APP = APP || {};
(function(app) {

var API_URLROOT = 'https://api.stackexchange.com/2.2/questions/';

app.xhr = {};

app.xhr.fetch = function(ids) {
return new Promise(function(resolve, reject) {
var url = makeApiUrl(ids);
var req = new XMLHttpRequest();
req.responseType = "json";
req.onload = function() {
if (this.status === 200) {
return resolve(this.response);
} else {
return reject('shit dun goofed');
}
}
req.open('GET', url);
req.send();
});
};

function makeApiUrl(questionIds) {
return API_URLROOT + questionIds + '?site=stackoverflow';
};

}(APP));