Books Won't Display for Reader App Exercise - javascript

I'm trying to get books to display based on the assignment above but can't figure out what is wrong for the life of me.
I built the service and modified the controller and view pages to the point where I believe they should display the books in the view, but I'm just seeing a blank page.
I feel like I am probably not retrieving the data properly and accessing it in the view/html.
Any ideas? Link to jsFiddle.
Index.html
<body ng-app="ReaderApp">
<div class="header">
<div class="container">
Reader
</div>
</div>
<div class="main">
<div class="container">
<div ng-view></div>
</div>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/BookshelfController.js"></script>
<script src="js/controllers/BookController.js"></script>
<script src="js/controllers/ChapterController.js"></script>
<!-- Services -->
<script src="js/services/books.js"></script>
</body>
js/apps.js
var app = angular.module('ReaderApp', ['ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when('/books', {
controller: 'BookshelfController',
templateUrl: 'views/bookshelf.html'
})
.otherwise({
redirecTo: '/books'
});
});
js/services/books.js
app.factory('books', ['$http', function($http) {
return $http.get('https://s3.amazonaws.com/codecademy-content/courses/ltp4/books-api/books.json')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
js/controllers/BookshelfController
app.controller('BookshelfController', ['$scope', 'books', function($scope, books) {
books.success(function(data) {
$scope.myBooks = data;
});
}]);
js/views/bookshelf.html
<div class="bookshelf row">
<!--
TODO: Loop through myBooks and display each one with this HTML
<div class="book col-md-3">
<a href="#/books/{{$index}}">
TODO: Add the book's cover here
<h3 class="title"> </h3>
<p class="author"> </p>
</a>
</div>
-->
<div class="book col-md-3" ng-repeat="book in myBooks">
<a href="#/books/{{$index}}">
<img ng-src="{{ book.cover }}">
<h3 class="title">{{ book.title }}</h3>
<p class="author">by {{ book.author }}</p>
</a>
</div>
</div>

I think I had the same trouble and my problem was in the router. Try adding array brackets ( [ ] ) and the '$routeProvider' string in your config method (app.js) like this:
app.config(['$routeProvider', function($routeProvider) {
// Normal router stuff goes here
}]);
Coming from Ember, the syntax is a little weird so I've been using this tutorial as reference when I get stuck.

Related

Filter files in folder and display them using ng-repeat (JS, Angular)

So, I've got some folder archives that contains unknown number of files, I know that:all of them got .7z extensionhalf starts with letters AB and other half - CD
So folder's content looks like:AB1234567890.7zAB2345678901.7zCD1234567890.7zCD2345678901.7z etc. That is I can do something like this:
Download
And on click it's gonna start downloading archive with name AB1234567890.7z. It's okay, but obviously I can't write links like that, it must be done with ng-repeat. So the question is - how to display 2 lists of links, where first list would be list with links which starts with AB and second - which starts with CD, respectively. Any help will be greatly appreciated :)
What about this:
angular.module('app',[]).controller('test', ['$scope', '$http', function($scope, $http){
//$http({ method: 'GET', url: '/getNames'}).then(function(names) {
// $scope.files = names;
//})
$scope.files = ['AB1234567890.7z',
'AB2345678901.7z',
'CD1234567890.7z',
'CD2345678901.7z'];
$scope.startWith = function(file, name){
return file.indexOf(name) == 0;
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='test'>
<p>First list</p>
<div ng-repeat='file in files' ng-if="startWith(file, 'AB')">
<a href='archives/{{file}}'>{{file}}</a>
</div>
<p>Second list</p>
<div ng-repeat='file in files' ng-if="startWith(file, 'CD')">
<a href='archives/{{file}}'>{{file}}</a>
</div>
</div>
I think this will help you
<div ng-controller="AppCtrl" layout="row" ng-cloak="" ng-app="MyApp">
<div layout="column" flex>
<a ng-repeat="file in archivesAB" href="archives/{{file}}" download="{{file}}">{{file}}</a>
</div>
<div layout="column" flex>
<a ng-repeat="file in archivesCD" href="archives/{{file}}" download="{{file}}">{{file}}</a>
</div>
</div>
(function () {
'use strict';
angular
.module('MyApp',['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
.controller('AppCtrl', AppCtrl);
function AppCtrl ($scope, $log) {
$scope.archivesAB = [
'AB1234567890.7z',
'AB2345678901.7z'
];
$scope.archivesCD = [
'CD1234567890.7z',
'CD2345678901.7z'
];
}
})();
And here is the working codepen

Angular Routing - Load data into parent page before first route

I am using angular routing for a admin panel project. Following is my angular js code.
app.js
(function() {
var app = angular.module("app", [
"ngRoute",
"app.dashboard",
"app.calendar",
"app.event"
]);
var dashboard = angular.module("app.dashboard");
dashboard
.config(function($routeProvider) {
$routeProvider.
when('/dashboard', {
templateUrl: '/views/dashboard/dashboard.html',
controller: 'DashBoardIndexController as ctrl'
}).
when('/dashboard/detail', {
templateUrl: "/views/dashboard/detailgraph.html",
controller: "DashBoardDetailController as ctrl"
})
});
......
......
//Controllers related to dashboard module
var calendar = angular.module("app.calendar");
calendar
.config(function($routeProvider) {
$routeProvider.
when('/calendar', {
templateUrl: '/views/calendar/calendar.html',
controller: 'CalendarIndexController as ctrl'
}).
when('/calendar/markevent', {
templateUrl: "/views/calendar/markevent.html",
controller: "CalendarEventController as ctrl"
})
});
......
......
//Controllers related to calendar module
}());
For better code management, I am dividing various module of application and including them in main app module.
After login, the first route loaded will be of dashboard (/dashboard). But before route provider initialized and dashboard loaded, I need to fetch the user's rights level and accordingly create the side navigation menus in parent page. Below is my parent page:
home.html
<body ng-app="app">
<header>
<nav id="mynav" class="bold z-depth-1" role="navigation">
<div class="nav-wrapper container">
<a id="logo-container" href="#" class="brand-logo text-darken-1">Logo</a>
<div class="container">
<a href="#" data-activates="slide-out" class="button-collapse top-nav full hide-on-large-only black-text"><i
class="mdi-navigation-menu"></i></a>
</div>
</div>
</nav>
<ul id="slide-out" class="side-nav fixed center-align">
<!-- This side menu items should be created based on user's rights --!>
</ul>
</header>
<main class="grey lighten-4">
<div id="main-container" class="container z-depth-1 ">
<div ng-view=""></div>
</div>
</main>
As you can see, before ng-view is loaded with first route (/dashboard), I need to make server call to fetch the user's rights. I am relatively new to angular and I think we can do this by resolve promise. But here two modules are different (app and app.dashboard).
What could be the correct way to solve this problem?

angularJS - controller stops working when I add ngRoute

So I'm trying to add routes to my angularJS app, and I'm running intro a problem where the main controller for my app stops working if I try to add 'ngRoute' to the app. Additionally, ngRoute is not working.
My code:
app.js (angular logic)
(function() {
angular.module('fccNight', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'results.html'
})
.otherwise({ redirectTo: '/' });
}])
//controllers
.controller('mainController', ['$scope', '$http', function($scope, $http) {
$scope.searchTerm = '';
$scope.data = [];
$scope.loading = false;
$scope.goingNo = [];
$scope.getResults = function() {
if($scope.searchTerm !== '') {
$scope.loading = true;
$scope.data = [];
$http.get('/api/search?term=' + $scope.searchTerm)
.success(function(results) {
$scope.loading = false;
$scope.data = results;
for(var i = 0; i < $scope.data.length; i++) {
$scope.goingNo.push($scope.data[i].going);
}
});
}
}
$scope.addGoing = function(index) {
// check if user is authenticated
if($scope.data[index].going > $scope.goingNo[index]) {
$scope.data[index].going -= 1;
}
else {
$scope.data[index].going += 1;
}
// register in db
}
}])
})();
index.html's body:
<body ng-controller="mainController" id="mainController">
<!-- CONTENT -->
<div class="container">
<div class="row text-center">
<div class="col-xs-12 main">
<h1>Where are you going tonight?</h1>
<p>Find nearby pubs and RSVP ahead of time.</p>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-8 col-lg-offset-2">
<form>
<div class="input-group">
<input id="inputSearch" ng-model="searchTerm" type="text" class="form-control" placeholder="Where are you?" autocomplete='off'>
<span id="goBtn" class="input-group-btn">
<a ng-click="getResults()" class="btn btn-default">Go</a>
</span>
</div>
</form>
</div>
</div>
<!-- LOADING -->
<div class="row loading hidden" ng-show="loading">
<div class="col-xs-12">
<div class="loader"></div>
</div>
</div>
<div class="text-center">Controller is working if search term is displayed: {{ searchTerm }}</div>
<!-- TEMPLATE -->
<div ng-view></div>
</div>
<!-- footer -->
<footer class="row-footer">
<div class="container">
<div class="row">
<div class="col-xs-12 text-center">
<a href="https://github.com/otmeek/fcc-night">
<i class="fa fa-github"></i>
</a> |
<a href="https://www.freecodecamp.com">
<i class="fa fa-fire"></i>
</a> | built using the Yelp API
</div>
</div>
</div>
</footer>
<!-- =====================SCRIPTS===================== -->
<!-- jQuery -->
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<!-- Bootstrap -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-route.js"></script>
<!-- custom scripts -->
<script src="js/app.js"></script>
<script src="js/scripts.js"></script>
</body>
results.html (the template I want to load in on '/' route)
<p>Results are loading</p>
<div class="row result" ng-repeat="result in data">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-8 col-lg-offset-2 result">
<div class="row">
<!-- image -->
<div class="col-xs-3 col-sm-2">
<div class="image">
<img ng-src="{{ result.image || 'img/noimage.jpg' }}">
</div>
<div ng-click="addGoing($index)" class="going text-center">
{{ result.going || 0 }} going
</div>
</div>
<!-- text -->
<div class="col-xs-9 col-sm-10">
<h4><a ng-href="{{ result.url || '#' }}">{{ result.name }}</a>
<small>{{ 'Rating: ' + result.rating || 'No rating available' }}</small></h4>
<p>{{ result.text || 'No reviews for this establishment.' }}</p>
</div>
</div>
</div>
</div>
As I said, if I remove all the routing logic from app.js and ng-view from index.html and just add in results.html, the app is running fine, controller is loading properly and everything is ok. But upon adding 'ngRoute' to the app, the results template doesn't load and I can't access any mainController variables or logic from index.html.
If anyone knows what I'm doing wrong please let me know. Thanks!
Edit: I just noticed the cdn for angular-route.js is not working. I can't find a download link for this library in the official site and I don't have bower so I have no idea where to get this file.
There is an error for angular-route.js
https://ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-route.js
its adress is wrong. There is no version for it. Write your version insteadof X.Y.Z
suchas https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-route.js
You need to change X.Y.Z by any specific version like 1.4.8 in your index.html page for angular route.
So you should use
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
instead of
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-route.js"></script>

Angularjs and routeParams

I have a piece of code that is getting JSON data from a local server. I am trying to display those data into a page and then when i'll click on a product i want to see the details of it. So far i can display all my products into a page but when i'm heading to the details page i got an error Cannot read property 'id' of undefined. Can you please help me out?
This is my code so far.
app.js
'use strict';
angular.module('app', []).
config(function($routeProvider){
$routeProvider.
when("/", {templateUrl: "/partials/products.html"}).
when("/details/:id", {templateUrl: "/partials/details.html", controller: DetailsCtrl}).
otherwise({redirectTo: "/"});
})
function AppCtrl($scope, $http){
$http.get('http://localhost:3000/api/products/727617361726372')
.success(function(data){
$scope.productList = data;
/*$scope.filterProductsByCategory = function(category){
$scope.search = category
};*/
})
.error(function(data){
console.log("Error!: ");
});
}
function DetailsCtrl($scope, $routeParams){
$scope.item = $scope.productList[$routeParams.id];
}
details.html
<h2>This is the details pages</h2>
product id: {{ item.product_id }}
<br/>
product name: {{ item.product_name}}
index.html
<div class="container" ng-app="app" ng-controller="AppCtrl">
<h1 class="text-danger">Welcome to our Store</h1>
<hr/>
<ng-view></ng-view>
</div>
products.html
<div class="col-lg-4 col-sm-6 col-xs-12" ng-repeat="product in productList">
<div class="thumbnail">
<img src="img/img3.jpeg">
<div class="caption">
<h4>{{ product.product_name }}</h3>
<p>Category: {{ product.category_name }} ({{ product.category_id }})</p>
<p class="text-muted">{{ product.product_details}}</p>
<ul class="list-inline">
<li>
<p class="product-price btn">€ {{ product.product_price }}</p>
</li>
<li>
Add to Cart
</li>
</ul>
</div>
</div>
Thanks!!!
you are getting the productList in your AppCtrl. If you want to access a specific item in your DetailsCtrl you'll need to get the specific item since you can't access AppCtrl scope variables in another Ctrl.
The best way to do this would be to create an extra rest call for getting a single item.
A quick way to fix your code, although I really don't recommend it would be to use $rootcope in your AppCtrl
I'd suggest reading Angular Docs on $scope. It might give you a better understanding how scopes work in angular:
https://docs.angularjs.org/guide/scope#!
I assume you have injected ngRoute correctly.
angular.module('app', ['ngRoute'])
Other than that there is nothing wrong with your code.
Demo
Just check your code again.

Template is compiled before the result is returenf from $http service

Hi I am trying to retrieve data from the server using $http, and correct data is being retrieved from the service, the data is -
[{
"URL":"someimg.jpg",
"TITLE":"Test Demo",
"DATE_ADDED":"2014-02-08 00:46:00",
"SUMMARY":"this is summary"
}]
the template that I wrote is as follows -
<article class="span8" ng-controller="allBlogs">
<div ng-show="success">
<div ng-repeat="blog in blogs.data">
<div class="row">
<div class="span3">
<img ng-src="{{blog['URL']}}" alt="" />
</div>
<div class="span5" ng-repeat-end>
<h4>{{blog.TITLE}}</h4>
<p>{{blog.DATE_ADDED}}</p>
<p>{{blog.SUMMARY}}</p>
</div>
</div>
</div >
</div>
</article>
the controller for the above template is as follows -
pk.controller("allBlogs", function($scope, $http, BlogsHandler){
$scope.success = false;
(function(){
BlogsHandler.getAllBlogs().success(function(data){
console.log(data);
$scope.success = true;
$scope.blogs = data.data;
});
})();
});
I am trying to set the success as true when the service returns data and thus the remaining part of the template should run. But this is not happening. Is it not that any change to $scope variable is being watched by the framework itself?
Help needed. I even tried with ng-switch with no effect.
Thanks
You assign data.data to $scope.blogs, so you don't need to add .data before blogs again.
$scope.blogs = data.data;
So, try this:
<div ng-repeat="blog in blogs track by $index">
<div class="row">
<div class="span3">
<img ng-src="{{blog.URL}}" alt="" />
</div>
<div class="span5">
<h4>{{blog.TITLE}}</h4>
<p>{{blog.DATE_ADDED}}</p>
<p>{{blog.SUMMARY}}</p>
</div>
</div>
</div >

Categories

Resources