Skip to content

Instantly share code, notes, and snippets.

@bmacmill
Created May 10, 2017 01:30
Show Gist options
  • Save bmacmill/9aa16f00ad73de2d288125b4b241a7d6 to your computer and use it in GitHub Desktop.
Save bmacmill/9aa16f00ad73de2d288125b4b241a7d6 to your computer and use it in GitHub Desktop.
$(document).ready(function() {
// Array to store all feed sources
//all caps b/c it's a const
var SOURCES = [{
displayName: "Reddit",
url: "https://www.reddit.com/r/worldnews/top/.json",
proxyRequired: false,
defaultSource: true, // You can have only one default source
formatResponse: function(response) {
var items = response.data.children;
//map method calling child -- we named child could hame anything
return items.map(function(child) {
return {
title: child.data.title,
author: child.data.author,
score: child.data.score,
link: child.data.url,
thumbnail: child.data.thumbnail,
tag: child.data.subreddit,
description: child.data.domain
};
});
}
}, {
displayName: "Mashable",
url: "http://mashable.com/stories.json",
proxyRequired: true,
defaultSource: false,
formatResponse: null
}, {
displayName: "Digg",
url: "http://digg.com/api/news/popular.json",
proxyRequired: true,
defaultSource: false,
formatResponse: null
}];
// Prefix url for proxy
var PROXY_URL = "https://accesscontrolalloworiginall.herokuapp.com/";
// Utils object to store any misc. methods
var Utils = {
markupFromArticles: function(articles) {
return _.map(articles, function(article) {
return Utils.markupFromSingleArticle(article);
}).join('');
},
markupFromSingleArticle: function(article) {
return Utils.articleTemplate(article);
},
articleTemplate: _.template('<article class="article clearfix">' + '<section class="featuredImage">' +
'<img src="<%= thumbnail %>" alt="">' + '</section>' + '<section class="articleContent">' +
'<a href=<%= link %> ><h3><%= title %></h3></a>' + '<h6><%= tag %></h6>' +
'</section>' + '<section class="impressions"><%= score %></section>' + '</article>')
};
// App object to store all app related methods
var App = {
init: function() {
// Methods that need to be called on initialization
App.bindEvents();
App.showDefaultFeed();
App.showDropDown();
App.searchButton();
},
showDefaultFeed: function() {
var defaultFeed = _.findWhere(SOURCES, {
defaultSource: true
});
App.showFeed(defaultFeed);
},
showDropDown: function() {
// replace with the forEach method
for (i = 0; i < SOURCES.length; i++) {
$('.sources-dropdown').append('<li><a href="#">' + SOURCES[i].displayName + '</a></li>');
}
},
//this is the formatted response of the raw api call
currentArticles: [],
showFeed: function(source) {
var request = App.requestFeed(source);
request.done(function(response) {
var currentArticles = source.formatResponse(response);
App.currentArticles = currentArticles;
App.renderArticles(currentArticles);
});
},
// add in fail scenario
// feedFail: request.fail(function(){
// alert("feed didn't load");
// });
requestFeed: function(source) {
var url = source.proxyRequired ? PROXY_URL + source.url : source.url;
App.setView('loader');
return $.ajax(url, {
dataType: 'json'
});
},
renderArticles: function(articles) {
App.setView('feed');
var articlesHTML = Utils.markupFromArticles(articles);
$("#main").html(articlesHTML);
},
//angels's solution to bind an event...
//a function listening to main where on click on an anchor the funciton alert runs...
//prevent default???
//this is were the article pop up opens
//need to put in content
bindEvents: function() {
$('#main').on('click', 'a', function(e) {
e.preventDefault();
App.setView('detail');
// console.log("you clicked on an article");
});
$('.closePopUp').on('click', function(e) {
e.preventDefault();
App.setView('feed');
});
},
searchButton: function() {
$("img").click(function() {
$("#search").toggleClass("active");
$(document).keydown(function(e) {
if (e.keyCode === 13) {
$("#search").removeClass("active");
}
});
});
},
setView: function(viewType) {
var $popup = $('#popUp');
var $closePopUp = $('.closePopUp');
if (viewType === 'loader') {
$popup.removeClass('hidden');
$closePopUp.addClass('hidden');
$popup.addClass('loader');
} else if (viewType === 'detail') {
$popup.removeClass('hidden');
$closePopUp.removeClass('hidden');
$popup.removeClass('loader');
} else if (viewType === 'feed') {
$popup.addClass('hidden');
$closePopUp.addClass('hidden');
}
}
};
App.init();
});
@donoage
Copy link

donoage commented May 14, 2017

  1. Struggle is good. It helps you grow! 🥇
  2. You figured out the part where you're populating the menu links. That's already an achievement.

Now for some thoughts.

https://gist.github.com/bmacmill/9aa16f00ad73de2d288125b4b241a7d6#file-app-js-L70

  • You classic loop works just fine. You can also use forEach(), $.each(), _.each(). Options are many and there's no one right answer!

https://gist.github.com/bmacmill/9aa16f00ad73de2d288125b4b241a7d6#file-app-js-L70

  • It's good to get into a habit of targeting specific elements with a class or an id. In this case, you want to look for .article a, utilizing the classname article.

https://gist.github.com/bmacmill/9aa16f00ad73de2d288125b4b241a7d6#file-app-js-L125-L129

  • Do not nest an event handler inside of another. This will attach the keydown handler to document every time a user opens up the search box.

Pointers for requirement features

Now that you have the menu links populated, we can do this for the click event handler for those menu links.

      $('.sources-dropdown').on('click', 'a', function(){
        // grab an object from SOURCES array using the text from each menu link. 
        // 'this' in javascript usually points to context of where this function was invoked. In this case, it'd be each of the menu links.
       // If  you clicked the reddit link from the dropdown, $(this).text(), would give you back 'Reddit'. And we're using that info to grab the object.
        var clickedSource = _.findWhere(SOURCES, { displayName: $(this).text() });
        App.showFeed(clickedSource);
      });

For these lines https://gist.github.com/bmacmill/9aa16f00ad73de2d288125b4b241a7d6#file-app-js-L111-L116

  • You want to grab things that you need from the article you clicked on and then append the info to the #popUp element
    $('#main').on('click', 'a', function(){
       e.preventDefault();
       App.setView('detail');
      // using the attr() method, you are grabbing the URL info from the article we clicked on,
      var articleUrl = $(this).attr('href');
      // We can also grab the title of the article.
      var title = $(this).find('h3').text();
      // here, you should use those vars to append to the popup!
     // add your own code here....!

    });

2/4

  • Missing some features from the requirements.

@bmacmill
Copy link
Author

Thanks for the feedback! as I said i really struggled with this, but i want to work on it more an understand it. I thought Saimon mentioned there was there a solution/working version of feedr somewhere. Is there?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment