Node/Express project using EJS partials and angular: Uncaught ReferenceError: angular is not defined - javascript

I feel like I have completely missed something here but I am trying to use ejs partials in a single page angular app. I keep getting a Uncaught ReferenceError: angular is not defined in my partial. I think this may have something to do with using ejs partials instead of using ng-include, however I have not had any luck in playing with that. Any help would be amazing.
app.js
(function(){
var app = angular.module('dashboard', []);
app.controller('ItemController', function(){
this.item = items;
});
//need to loop through items in DB for now using these test objects
var items = [
{
name : 'name1',//query to db for name goes here
stock : '4',//query to db
img : '/images/bb-logo.png'//query to db
},
{
name : 'name2',//query to db for name goes here
stock : '6',//query to db
img : '/images/bb-logo.png'//query to db
}
];
})();
index.ejs
<!DOCTYPE html>
<html lang="en" ng-app="dashboard">
<head>
<meta charset="UTF-8">
<title><%= title %></title>
<link rel="stylesheet" href='/libs/font-awesome/css/font-awesome.css'>
<link rel="stylesheet" href='/libs/foundation/css/foundation.css'>
<link rel="stylesheet" href='/stylesheets/style.css'>
<!-- include angular here -->
<script type="text/javascript" href='/libs/angular/angular.js'></script>
<script type="text/javascript" href='/libs/modernizer/modernizer.js'></script>
<script type="text/javascript" src="/angularApp.js"></script>
</head>
<body>
<% include partials/topbar %>
<div class="row">
<div class="large-6 columns etsy-container">
<% include partials/etsy-container %>
</div>
<div class="large-6 columns">
<% include partials/amazon-container %>
</div>
</div>
</body>
</html>
/amazong-container
<div class='store-container'>
<h1 class="left">Amazon</h1>
<span class="store-utility-icons"><i class="fa fa-refresh right"></i><i class="fa fa-times-circle-o right"></i></span>
<div class="clear"></div>
<% include /item %>
</div>
/item.ejs
<div ng-controller="ItemController as store" >
<div ng-repeat="item in store.items">
<img ng-src="{{item.img}}" />
<p>{{item.name}} <i> Stock level: {{item.stock}}</i></p>
</div>
</div>

The way you include Angular is wrong. You have
<script type="text/javascript" href='/libs/angular/angular.js'></script>
but it should be:
<script type="text/javascript" src="/libs/angular/angular.js"></script>
So you have to use src instead of href. Looks like a typical copy/paste error. So, in the end, this has nothing to do with EJS or using partials, it's just wrong HTML ;-).
PS: Apart from that, you're using single quotes for attributes in HTML. Go with double quotes all the times, as this is the usual and common way to do it.
PPS: The same applies to the line where you try to load Modernizr.

Related

AngularJS simple app webpage stops rendering code

I'm trying to go through an AngularJS tutorial on codeschool.com but as I work through it and refresh my browser to see my progress, at some point in the tutorial the browser always ends up loading a blank webpage and won't load the code anymore. I've attempted the tutorial from the start twice and it happened both times at different points.
I must keep doing something wrong in my code. Has anyone else had this issue or know how to fix it?
I've seen a couple similar questions on here but the answers haven't worked.
Here's the HTML:
<!DOCTYPE html>
<html ng-app='store'>
<head>
<html lang="en-US">
<link rel="stylesheet/css" type="text/css" href="bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
</head>
<body ng-controller="StoreController as store">
<div ng-repeat="product in store.products">
<h1> {{store.product.name}} </h1>
<h2> {{store.product.price}} </h2>
<p> {{store.product.description}} </p>
<button>Add to Cart</button>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
And here's the JS file:
(function (){
const app = angular.module('store', [ ]);
app.controller("StoreController", function(){
this.product = gems;
});
const gems = [
{
name: "Dodecahedron",
price: 2.95,
description: 'Many sided gem. Would look great in a ring.',
},
{
name: "Pentagonal Gem",
price: 5.95,
description: 'A gem shaped like a pentagon. More expensive and
more shiny',
}
];
})();
Two things: you have a mismatched variable name between your controller and your view and then inside your ng-repeat you are including your controller alias instead of accessing each of the repeated elements directly.
First change this.product = gems; in your controller to this.products = gems; and then change your ng-repeat div to this:
<div ng-repeat="product in store.products">
<h1> {{product.name}} </h1>
<h2> {{product.price}} </h2>
<p> {{product.description}} </p>
<button>Add to Cart</button>
</div>

Multiple controllers working within ngRoute example

I have a small ngRoute example I am trying that to use multiple applications and controllers with. The first app/controller is for the main page, while the second set of app/controller is for the html that ngRoute loads up after pressing a button. However, it doesn't seem to be working. Code below:
Main Module
var app = angular.module("MainModule", ["ngRoute"]);
Main Controller
app.controller("MainController", function ($scope) {
});
app.config(function ($routeProvider) {
$routeProvider
.when('/customers', {
templateUrl: "customers.html",
controller: "CustomerController"
})
});
Customer Module
var CustomerModule = angular.module("CustomerModule", []);
Customer Controller
CustomerModule.controller("CustomerController", function ($scope) {
$scope.Test = "Hey";
$scope.CustomerArray = [
{ "firstName" : "John", "lastName" : "Williams", "Occupation" : "Fireman" },
{ "firstName" : "Louis", "lastName" : "Abrams", "Occupation" : "Policeman" }
]
});
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script src="scripts/MainModule.js"></script>
<script src="scripts/MainController.js"></script>
<link rel="stylesheet" type="text/css" href="MyCSS.css">
</head>
<body>
<div ng-app="MainModule">
<div id="TopDiv">Main Module</div>
<input type="button" value="Load Customers" />
<div ng-view></div>
</div>
</body>
</html>
customers.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="scripts/CustomerModule.js"></script>
<script src="scripts/CustomerController.js"></script>
</head>
<body>
<div ng-app="CustomerModule" ng-controller="CustomerController">
{{Test}}
<ul>
<li ng-repeat="x in CustomerArray">{{x.firstName x.lastName x.Occupation}}</li>
</ul>
</div>
</body>
</html>
Long bits of code there, but hopefully simple code. The output when I press the "Load Customer" button is literally {{Test}} with no array data to follow.
I am just now learning angular, so any help with this issue I would appreciate. I am just doing this for fun, to try to learn. So I suppose the issue is not pressing. :) Thanks!
I wrote out a working example using the code from the question as a base. There are quite a few adjustments that were made, so I will list each piece with a bit of explanation.
It is not necessary for each "page" to have it's own module. However, it is not a bad practice. To support the design you have here of one module for each view, I made the following changes:
Include the CustomerModule as a dependency in the MainModule (MainModule.js):
var app = angular.module("MainModule", ["ngRoute", "CustomerModule"]);
Load ALL scripts in the index.html:
<script src="scripts/MainModule.js"></script>
<script src="scripts/MainController.js"></script>
<script src="scripts/CustomerModule.js"></script>
<script src="scripts/CustomerController.js"></script>
With these changes, the $routeProvider is able to locate the CustomerController and instantiate it during a route change. The customers.html now does not have to create a controller, and can be stripped down to a complete partial. Also, the expression used in customers.html needed to be changed, and broken down into individual expressions for each property.
The final customers.html:
{{Test}}
<ul>
<li ng-repeat="x in CustomerArray">{{x.firstName}} {{x.lastName}} {{x.Occupation}}</li>
</ul>
Complete working sample on plnkr.co: http://plnkr.co/edit/EjwW9Fsc2DPhBejUETwB?p=preview
I'm not sure, but the problem is in your MainModule. It should be like this or so:
var app = angular.module("MainModule", ["ngRoute"]);
When you calling angular.module with only one parameter - it's only trying get module, not create.
And customers.html should only contains parts of you html, not full:
Full customers.html
{{Test}}
<ul>
<li ng-repeat="x in CustomerArray">{{ x.firstName }} {{ x.lastName }} {{ x.Occupation }}</li>
</ul>
And add move customer js files to index.html:
<script src="scripts/MainModule.js"></script>
<script src="scripts/MainController.js"></script>
<script src="scripts/CustomerModule.js"></script>
<script src="scripts/CustomerController.js"></script>
<link rel="stylesheet" type="text/css" href="MyCSS.css">
Hope, it helps.

Import Json data and show it in angular app

i started learning angular a week ago, and now im trying to construct a app by myself (because people say that is the best way to learn), im trying to do a thing that i didnt before so dont be so rude to me if it is easy, im trying to build a pokedex, im trying to use data that already exist for it in Json, and import it to the controller on angular so i can use ng-repeat to show the data, but i dont know why it doesnt result, maybe im doing a lot of mistakes but i cant find it :/ , i will post what i did here:
Html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="angular.js"></script>
<script src="pokedex.js"></script>
<body ng-app ="pokedex">
<div class="row">
<div class="col-md-offset-1 form-group">
<label for="sel1">Select list:</label>
<select class="form-control">
<option>All</option>
<option>Normal</option>
<option>Watter</option>
<option>Fire</option>
<option>Eletric</option>
<option>Rock</option>
<option>Ice</option>
<option>Grass</option>
<option>Psychic</option>
<option>Poison</option>
<option>Dragon</option>
</select>
</div>
</div>
<div class="row" ng-controller="PokemonController as pokedex">
<div class="col-md-offset-1 col-md-6" ng-repeat = "pokemon in pokedex.pokemons">
<p>Name: {{pokemon.Name}}</p>
</div>
</div>
script
(function(){
var app = angular.module('pokedex',[]);
app.controller('pokemonController',['$http',function($http){
var pokemons = this;
$http.get('https://pokedex-deluxor.rhcloud.com/getall').success(function(data){
pokemons = data;
});
}]);
});
Json Url: Pokedex
Ps: Sorry about my bad english friends :/
ng-repeat = "pokemon in pokedex.pokemons"
you are using ng-repeat on pokedex.pokemons you have to assign data to pokedex.pokemons from controller where you are getting data.
$http.get('https://pokedex-deluxor.rhcloud.com/getall').success(function(data){
// assign data here
});
you should assign the data returned from your http request to the scope object pokemons.
since you used controller as syntax you should do
JS
(function(){
var app = angular.module('pokedex',[]);
app.controller('pokemonController',['$http',function($http){
$http.get('https://pokedex-deluxor.rhcloud.com/getall').success(function(data){
this.pokemons = data;
});
}]);
});
HTML
<div class="row" ng-controller="PokemonController as pokedex">
<div class="col-md-offset-1 col-md-6" ng-repeat = "pokemon in pokedex.pokemons">
<p>Name: {{pokemon.Name}}</p>
</div>

Invalid characters and modules when translating a node.js app from javascript to coffee script

So basically I'm trying to follow the tutorial listed here, except using coffee script instead of javascript. I'm getting two errors on the website, 1. A syntax error regarding the '#' character in the first line of core.coffee (# public/core.coffee) 2. an error that says no module: scotchTodo.
On the actual page, instead of showing the number of todos and each todo, it says
{{ todos.length }} and {{ todo.text }}.
Here's my core.coffee:
# public/core.coffee
scotchTodo = angular.module 'scotchTodo', []
mainController = ($scope, $http) ->
$scope.formData = {}
# when landing on the page, get all todos and show them
$http.get '/api/todos'
.success((data) ->
$scope.todos = data
console.log data
).error((data) ->
console.log 'Error: ' + data
)
# when submitting the add form, send the text to the node API
$scope.createTodo = ->
$http.post '/api/todos', $scope.formData
.success((data) ->
$scope.formData = {} # clear the form so our user is ready to enter another
$scope.todos = data
console.log data
).error((data) ->
console.log 'Error: ' + data
)
# delete a todo after checking it
$scope.deleteTodo = (id) ->
$http.delete '/api/todos/' + id
.success((data) ->
$scope.todos = data
console.log data
).error((data) ->
console.log 'Error: ' + data
)
Here's my index.html:
<!-- index.html -->
<!doctype html>
<!-- ASSIGN OUR ANGULAR MODULE -->
<html ng-app="scotchTodo">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->
<title>Todo App</title>
<!-- SCROLLS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"><!-- load bootstrap -->
<style>
html { overflow-y:scroll; }
body { padding-top:50px; }
#todo-list { margin-bottom:30px; }
</style>
<!-- SPELLS -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script><!-- load jquery -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script><!-- load angular -->
<script src="core.coffee"></script>
</head>
<!-- SET THE CONTROLLER AND GET ALL TODOS -->
<body ng-controller="mainController">
<div class="container">
<!-- HEADER AND TODO COUNT -->
<div class="jumbotron text-center">
<h1>I'm a Todo-aholic <span class="label label-info">{{ todos.length }}</span></h1>
</div>
<!-- TODO LIST -->
<div id="todo-list" class="row">
<div class="col-sm-4 col-sm-offset-4">
<!-- LOOP OVER THE TODOS IN $scope.todos -->
<div class="checkbox" ng-repeat="todo in todos">
<label>
<input type="checkbox" ng-click="deleteTodo(todo._id)"> {{ todo.text }}
</label>
</div>
</div>
</div>
<!-- FORM TO CREATE TODOS -->
<div id="todo-form" class="row">
<div class="col-sm-8 col-sm-offset-2 text-center">
<form>
<div class="form-group">
<!-- BIND THIS VALUE TO formData.text IN ANGULAR -->
<input type="text" class="form-control input-lg text-center" placeholder="I want to buy a puppy that will love me forever" ng-model="formData.text">
</div>
<!-- createToDo() WILL CREATE NEW TODOS -->
<button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add</button>
</form>
</div>
</div>
</div>
</body>
</html>
Please let me know if you need anything else from me, really trying to understand what's going on. Thanks!
You seem to be trying to use CoffeeScript in the browser:
<script src="core.coffee"></script>
You need to either compile it first, or ad the compiler to your browser code so it can be compiled on the fly. The latter is generally not a good idea, so you should add a build step that uses the CoffeeScript compiler to turn your core.coffee into core.js, then include that script in your index.html.
From the terminal that would look something like coffee -c core.coffee, but there are more options as can be seen here.

Restify server with Angular, not working

I am learning to use Restify to build a Restful API and work with Angular.
Below is my structure:
Project
page_admin
core.js
index.html
node_modules
restify
mongojs
server.js
I had set up server and implemented several API calls.
Below news API return a list of JSON data in browser:
`http://localhost:8080/news`
`[{"_id":"53b2a2c3373551813dfe8b91","title":"first","subtitle":"foobar","textbody":"","postedOn":"2014-07-01T12:00:03.215Z"},{"_id":"53b2a122373551813dfe8b8e","title":"my second","subtitle":"my second title","textbody":"node is cool","postedOn":"2014-07-01T11:53:06.389Z"},{"_id":"53b2a0cd373551813dfe8b8d","title":"delay announcement","subtitle":"sub ","textbody":"I am the text body","postedOn":"2014-07-01T11:51:41.678Z"}]`
here is my code to handle client side route:
server.get('/', restify.serveStatic({
'directory': './page_admin',
'default': 'index.html'
}));
My index.html is simple:
<!-- index.html -->
<!doctype html>
<!-- ASSIGN OUR ANGULAR MODULE -->
<html ng-app="bluesky">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->
<title>My test app</title>
<!-- SCROLLS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"><!-- load bootstrap -->
<style>
html { overflow-y:scroll; }
body { padding-top:50px; }
#todo-list { margin-bottom:30px; }
</style>
<!-- SPELLS -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script><!-- load jquery -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script><!-- load angular -->
<script src="core.js"></script>
</head>
<!-- SET THE CONTROLLER AND GET ALL TODOS -->
<body ng-controller="mainController">
<div class="container">
<!-- HEADER AND TODO COUNT -->
<div class="jumbotron text-center">
<h1>My example is working <span class="label label-info">{{ news.length }}</span></h1>
</div>
<!-- TODO LIST -->
<div id="todo-list" class="row">
<div class="col-sm-4 col-sm-offset-4">
<!-- LOOP OVER THE TODOS IN $scope.todos -->
<div class="checkbox" ng-repeat="new in news">
<label>
<input type="checkbox" ng-click="deleteTodo(new._id)"> {{ new.subtitle }}
</label>
</div>
</div>
</div>
</div>
</body>
</html>
core.js is like this:
var bluesky = angular.module('bluesky', []);
function mainController($scope, $http) {
$scope.formData = {};
$http.get('/news')
.success(function(data) {
$scope.news = data;
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
}
when I try to navigate to: http://localhost:8080
I got my index page but it shows me:
'My example is working {{ news.length }}
and in console, I saw following error:
GET `http://localhost:8080/core.js` 404 (Not Found)
localhost/:24
Uncaught Error: No module: bluesky
angular.min.js:18
what I just missed so that the angular is not retrieving the data?
=============================================================
upate
if I directly include core.js put code inside , then it works.
but, how to solve this 404 not found issue? just don't want to include all js files in the index page.
As far as my knowledge about angular js, controller is not defined in your module. So instead of using function mainController($scope, $http) {
....
}
you should define controller inside the module bluesky as follows
bluesky.controller("mainController",function($scope,$http)
{
....
});

Categories

Resources