I have been working on a hacker news client using the official hacker news firebase API and Angular.js. Everything seems to be working fine except for the 'jobstories' posts, which are not rendering on the screen even though the story IDs are being logged to the console. This is quite puzzling as the code works perfectly fine for 'topstories', 'maxitem', and 'showstories'. For those interested, here is the link to the Plunker.
angular.module('app.services', ['ngColorThis', 'ngTouch']).factory('HackerNews', function() {
return new Firebase('https://hacker-news.firebaseio.com/v0');});
angular.module('app.controllers', ['app.services']).controller('AppController', [
'$scope', '$sce', '$timeout', '$window', '$q', 'HackerNews', function($scope, $sce, $timeout, $window, $q, HackerNews) {
$scope.section = 'top';
$scope.gotoStory = function(story) {
$scope.currentStory = story;
$scope.storyUrl = $sce.trustAsResourceUrl(story.url);
return $scope.navi.pushPage(cordova.ThemeableBrowser.open(story.url, '_blank', {toolbar: {
height: 44,
color: 'transparent'
}, closeButton: {
image: 'ic_cancel_black',
imagePressed: 'close_pressed',
align: 'left',
event: 'closePressed'
}}));
};
$scope.loadUrl = function(url) {
return $window.open(url, '_blank', 'location=yes');
};
return $scope.getStory = function(id) {
var deferred, timer;
deferred = $q.defer();
timer = $timeout(deferred.resolve, 1000);
HackerNews.child("item/" + id).once('value', function(data) {
var item;
item = data.val();
if (item && item.type === 'story' && !item.deleted && item.url) {
$timeout.cancel(timer);
return deferred.resolve(item);
} else {
$timeout.cancel(timer);
return deferred.resolve();
}
});
return deferred.promise;
};
}
]).controller('JobController', [
'$scope', '$q', 'HackerNews', function($scope, $q, HackerNews) {
$scope.stories = [];
$scope.getJobStories = function() {
return HackerNews.child('jobstories').once('value', function(data) {
var i, id, jobId, len, promises;
console.log(data.val());
jobId = data.val();
promises = [];
for (i = 0, len = jobId.length; i < len; i++) {
id = jobId[i];
promises.push($scope.getStory(id));
}
return $q.all(promises).then(function(stories) {
stories = stories.filter(function(story) {
return typeof story !== 'undefined';
});
if (stories.length > 0) {
return $scope.stories = stories;
}
});
});
};
return HackerNews.child('jobstories').on('value', $scope.getJobStories);
}
]);
<ons-template id="jobs.html">
<ons-navigator var="navi">
<ons-list ng-controller="JobController">
<ons-list-item modifier="tappable" ng-repeat="story in stories" ng-click="gotoStory(story); showme=true;">
<div ng-hide="showme">
<div style="padding: 0 10px 0 10px;">
<span color-this="color" data-color="story.title" class="story-title">{{ story.title }}</span>
<span color-this="color" data-color="story" class="story-site">({{ story.url | urlToHost }})</span>
<span style="display:inline" class="story-info">{{ story.score }} points by</span><span style="display:inline" color-this="color" data-color="story.title" class="story-info"> {{ story.by }} </span><span style="display:inline" class="story-info">{{ story.time | timeAgo }}</span>
</div>
</div>
<div ng-show="showme" style="opacity:0.4" color-this="background" data-color="story.title">
<div style="padding: 0 10px 0 10px;">
<span class="story-title">{{ story.title }}</span>
<span color-this="color" data-color="story" class="story-site">({{ story.url | urlToHost }})</span>
<span class="story-info">{{ story.score }} points by {{ story.by }} {{ story.time | timeAgo }}</span>
</div>
</div>
</ons-list-item>
</ons-navigator>
</ons-template>