AngularJS Webpage Can't Find Referenced Angular Module or Controller - javascript

Sorry for the possible repost, but I don't know how else to write this. I've been using this website to create a small angularJS webpage using nodeJS as well, and I've gotten to the part of separating the angular code from the view, or HTML. What I've found was that when I tried to separate them nothing worked any more.
Here's my code so far:
Home.html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<!-- <script>
var myApp = angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.myColor = "red";
});
</script> -->
</head>
<body>
<!-- <script>
myApp.directive('myDirective', function() {
return {
template: "This is a test directive."
};
})
</script> -->
<h2>myApp Test</h2>
<div ng-app="myApp" ng-controller="myCtrl" ng-init="quantity = 10; cost = 5">
<p>Color: <input type="text" style="background-color:{{myColor}}" ng-model="myColor" value="{{myColor}}"></p>
<p>Total in dollar (raw exp): {{quantity * cost}}</p>
<p>Total in dollar (span): <span ng-bind="quantity * cost"></span></p>
<p> First Name: <input type="text" ng-model="firstName"></p>
<p> Last Name: <input type="text" ng-model="lastName"></p>
<h1>Hello, {{firstName + " " + lastName}}</h1>
</div>
Are you even changing?!
</body>
<script type="javascript" src="../JS/myApp.js"></script>
<!-- <script type="javascript" src="../JS/myApp.module.js"></script> -->
<script type="javascript" src="../JS/myCtrl.js"></script>
<!-- <script type="javascript" src="../JS/myCtrl.component.js"></script> -->
</html>
myApp.js / myApp.module.js:
var myApp = angular.module('myApp', []);
myCtrl.js / myCtrl.component.js:
myApp.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.myColor = "red";
});
// app.directive('myDirective', function() {
// return {
// template: '<p><h3>This is a test directive.<h3></p>'
// };
// });
Finally, here's my folder hierarchy:
If what I've done wrong is already evident, there's no need for you to continue reading.
Now the commented-out code is important as well. These are both the other things I've tried, and what I wanted to implement. I have tried:
Re-adding all the angular code back to the head tag to make sure it was still working at all. It worked, aside from the directive stuff (which, at point, I believe would have to be part of a separate module, but not the point, nonetheless).
Moving the script references, which are, and were, located below the body, to the head.
Moving the script references to the top of the body.
Moving everything into just *one* file (myApp.module.js).
Renaming both "myCtrl.component.js" and "myApp.module.js" to "myCtrl.js" and "myApp.js", respectively, to ensure possibly-antiquated angularJS nomenclature wasn't an attribution.
Adding "type="javascript"" to the script references.
"Hard refreshing" to make sure old documents weren't cached.
Tested to see if it was even requesting the files from the server using node. It doesn't look like it is.
If you need the nodeJS part of it, it's here as well (index.js):
var http = require('http');
var url = require('url');
var fs = require('fs');
var path = require('path');
http.createServer(function(req, res) {
var myUrl = url.parse(req.url);
var basename = path.basename(myUrl.path);
console.log('request url: ' + req.url);
console.log('url path: ' + myUrl.path);
console.log('basename: ' + basename);
fs.readFile('../HTML/Home.html', function(err, data) {
res.writeHead(200, { 'ContentType': 'text/html' });
res.write(data);
res.end();
});
}).listen(8080);

The problem is in your script tag
<script type="javascript" src="../JS/myCtrl.js"></script>
It should not be
type="javascript"
Either change it to
type="text/javascript"
or remove the type totally. Due to incorrect type , it is not loading controller and other js files to browser.

Related

Application's html loads, but js function built with angular gets stuck loading indefinitely

I'm working on an AngularJS application that reads and writes cookies and my javascript code is not working properly. My html loads fine, but when it comes to load the angular script it gets stuck loading indefinitely.
I've tried with a simple 'hello world' console log with a simple angular function and it works fine, which means the problem is not located on the angular script, but on the cookie function itself, although I can't point out where and since the page's not loading at all, I can't see any output on the console.
Here's my html code.
<!doctype html>
<html ng-app = 'cookieApp'>
<head>
<meta charset="utf-8">
</head>
<body>
<div ng-controller = 'MainController'>
<label>Save cookie:</label>
<input ng-model = 'value'>
<button ng-click = 'saveCookie(value);'>Save</button>
<h2>Get Cookie : {{getCookie()}}</h2>
<script src = 'https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.js'></script>
<script src = 'app.js'></script>
</div>
</body>
</html>
Here's the javascript code
angular.module('cookieApp', []).controller('MainController', ['$scope', 'cookie', function($scope, cookie){
$scope.value = '';
$scope.saveCookie = function(value){
cookie.write('cap_value', value);
}
$scope.getCookie = function(){
return cookie.read('cap_value');
}
}]).
factory('cookie', [function(){
return{
read: function(name){
var i, c, nameEQ = name + '=';
var ca = document.cookie.split(';');
for(i = 0; i < ca.length; i++){
c = ca[i];
while(c.charAt(0) == ''){
c = c.substring(1, c.length);
}
if(c.indexOf(nameEQ) == 0){
return c.substring(nameEQ.length, c.length);
}
}
return '';
},
write: function(name, value){
date = new Date();
date.setTime(date.getTime() + (72*4));
expires = '; expires = ' + date.toGMTString();
document.cookie = name + '=' + value + expires + '; path = /';
}
}
}]);
I expect the application to save a cookie when I type an input and then print it in the <h2> tag.
Not sure if you're aware of the ngCookies module, but it's basically the answer to your problem. It provides the $cookies service, which is the "proper" way to work with cookies, within an AngularJS application. I've combined your HTML and JavaScript into this snippet, which works exactly as I think you're expecting:
<!doctype html>
<html lang="en" ng-app='cookieApp'>
<head>
<meta charset="UTF-8">
<title>AngularJS Cookie Example</title>
</head>
<body>
<div ng-controller='MainController'>
<label>Save cookie:</label>
<input ng-model='value'>
<button ng-click='saveCookie(value);'>Save</button>
<h2>Get Cookie : {{getCookie()}}</h2>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.js'></script>
<!-- including the ngCookies module here -->
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular-cookies.js'></script>
<script>
// adding `ngCookies` to the dependencies
angular.module('cookieApp', ['ngCookies']).controller('MainController', ['$scope', '$cookies', function ($scope, $cookies) {
$scope.value = '';
$scope.saveCookie = function (value) {
$cookies.cap_value = value;
};
$scope.getCookie = function () {
return $cookies.cap_value;
};
}]);
</script>
</div>
</body>
</html>
I'll point out that the API changed in version 1.4, they added getters and setters. Just be aware of that, if you decide to upgrade your AngularJS version at some point in the future.

Skulpt example not work in Plunker

I'm new to Plunker so this may be a noob question...But I really struggled a long time and haven't figured it out yet.
I tried to test the example code published on Skulpt's main site in Plunker but it just didn't work. But it did work in local server.
Here's my plunker link
Here's the code:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script>
<script src="http://www.skulpt.org/static/skulpt.min.js" type="text/javascript"></script>
<script src="http://www.skulpt.org/static/skulpt-stdlib.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
// output functions are configurable. This one just appends some text
// to a pre element.
function outf(text) {
var mypre = document.getElementById("output");
mypre.innerHTML = mypre.innerHTML + text;
}
function builtinRead(x) {
if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
throw "File not found: '" + x + "'";
return Sk.builtinFiles["files"][x];
}
// Here's everything you need to run a python program in skulpt
// grab the code from your textarea
// get a reference to your pre element for output
// configure the output function
// call Sk.importMainWithBody()
function runit() {
var prog = document.getElementById("yourcode").value;
var mypre = document.getElementById("output");
mypre.innerHTML = '';
Sk.pre = "output";
Sk.configure({output:outf, read:builtinRead});
(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'mycanvas';
var myPromise = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("<stdin>", false, prog, true);
});
myPromise.then(function(mod) {
console.log('success');
},
function(err) {
console.log(err.toString());
});
}
</script>
<h3>Try This</h3>
<form>
<textarea id="yourcode" cols="40" rows="10">import turtle
t = turtle.Turtle()
t.forward(100)
print "Hello World"
</textarea><br />
<button type="button" onclick="runit()">Run</button>
</form>
<pre id="output" ></pre>
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas"></div>
</body>
</html>
Your code requests http resources and is being run from the https version of Plunker. Plunker's editor can be opened either in https or in http though I encourage the former.
Modern browsers will now block the loading of http resources from an https website (such as the preview of your Plunk). You can observe this by opening the developer console where you will see messages about blocked requests.
You have two options:
Open your saved Plunk via http (your plunk over http)
Adjust the resources that your plunk requests to come from an https:// scheme:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script>
<script src="https://www.skulpt.org/static/skulpt.min.js" type="text/javascript"></script>
<script src="https://www.skulpt.org/static/skulpt-stdlib.js" type="text/javascript"></script>

Why wont my jsp page recognize my angular controller?

jsp page
<!DOCTYPE html>
<html data-ng-app="myApp">
<head><title>Sample JSP Page</title></head>
<body>
<div data-ng-contoler="mainController" >
<input type="text" data-ng-model="greeting">
This is from angular {{greeting}}
</div>
<button data-ng-click="test()">doSomething</button>
</body>
<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="js/jquery.min.js"></script>
<script src="js/toast.js"></script>
<script src="app/app.js"></script>
<script src="app/mainController.js"></script>
<script src="app/services.js"></script>
</html>
My module myApp
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(function($logProvider){
$logProvider.debugEnabled(true);
});
My mainController.js
myApp.controller('mainController',function($scope, $http, myAppFactory) {
$scope.greeting = null;
$scope.greeting = "Jo jo jo it worked!!!!";
$scope.test = function test(){
var v= "asddas";
myAppFactory.test().success(function(date){
var a = data;
})
}
});
My service.js myAppFactory
myApp.factory('myAppFactory', function($http) {
var factory = {};
factory.test = function(){
return "test";
}
return factory;
});
When i press the doSomething button it should go to scope.test
The problem is that the controller is not available.
When i start eclipse, and go to the page on chrome, press f12
i can find the contoller with my code in it, but it never runs.
On start the "greeting" is set to be:
$scope.greeting = null;
$scope.greeting = "Jo jo jo it worked!!!!";
But on the page it is blank, on f12 i see with breakpoints that the code
never worked.
The input field with the data-ng-model="greeting"
is working fine. When i go to the page and write something in it
it is instantly displayed on change.
All files are loaded on the debug window. app, mainController and service.
On load the pages gets all files with status 200 OK
But i cant enter with breakpoints in the mainController.
change typing mistake
<div data-ng-contoler="mainController" >
to
<div data-ng-controller="mainController" >
Hope it will work.

adding div using javascript that uses angularjs to show data

I would like to add a div to my current website.
The div i would like to add should show some json data using angularjs.
My problem is that it does not look like angularjs is working like its supose to when adding html after the page is rendered.
Here is my test:
<html >
<head>
<meta charset="utf-8">
<title>Angular test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</head>
<script>
var featureInfoMainDivId = 'FeatureInfoMaster';
function initAngularDataFeatureInfo() {
var s = document.createElement('script');
s.type = "text/javascript";
s.textContent =
'var app = angular.module("featureInfoApp", []); ' +
'app.controller("featureInfoCtrl", function ($scope) { ' +
'$scope.firstName = "John" '+
'$scope.lastName = "Doe" ' +
'});';
document.getElementById(featureInfoMainDivId).appendChild(s);
}
function addFeatureInfoDiv() {
var divMain = document.createElement('div');
divMain.setAttribute('id', featureInfoMainDivId);
divMain.setAttribute('ng-app', "featureInfoApp");
divMain.setAttribute('ng-controller', "featureInfoCtrl");
divMain.innerHTML ='<div> {{ firstName + " " + lastName }}</div>';
document.getElementById('appdiv').appendChild(divMain);
initAngularDataFeatureInfo();
}
</script>
<body >
<div id="appdiv"></div>
<button id="btn_load_grid" onclick="addFeatureInfoDiv();">loaddata</button>
</body>
</html>
You are missing two semicolons in
$scope.firstName = "John";
$scope.lastName = "Doe";
If you load the Angular script it looks for ng-app and bootstraps itself. Since you add Angular specific code after the script is loaded, you need to bootstrap Angular manually with:
//after initAngularDataFeatureInfo();
angular.element(document).ready(function() {
angular.bootstrap(document, ['featureInfoApp']);
});
Please remove this line:
divMain.setAttribute('ng-app', "featureInfoApp");
It is not needed if you bootstrap Angular manually. For further bootstrapping info, see: Angular bootstrapping documentation.
Also: Is there a reason why you are using Angular version 1.2.26? Version 1.5.3 is the latest stable build.
Try using Angular directives. you can create a customer directive which will then feed a template of your liking

How to load different html files in QUnit?

I'm using QUnit for unit testing js and jquery.
My HTML looks like this:
<!DOCTYPE html>
<html>
<head>
<title>QUnit Test Suite</title>
<script src="../lib/jquery.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.16.0.css" type="text/css" media="screen">
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<!--This is where I may have to add startPage.html--->
<script src="../login.js"></script>
<script src="../test/myTests.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
Currently, I'm adding login.js as shown and I'm getting references correctly to objects defined in login.js.
However, functions in login.js contains references to some dom elements defined in startPage.html which is located elsewhere.
So, if I say $('#login-btn'), it is throwing an error. Is there any way to fix this?
Can I
(a) refer to startPage.html to my qunit page given above?
(b) refer to or load startPage.html in the file where I'm running tests (myTests.js):
QUnit.test( "a test", function( assert ) {
assert.equal( 1, "1", "String '1' and number 1 have the same value" );//works
assert.equal( login.abc, "abc", "Abc" );//works with attributes
assert.equal(($("#userid").val()),'', 'Userid field is present');//fails
assert.equal( login.ValidUserId(), true, "ValidUserId" );//fails with functions
});
Does QUnit provide any method to load Html/php files so they'll be defined prior to testing. Like 'fixtures' in jasmine?
EDIT: Please also tell what to do in case I have startPage.php
There are a couple of ways you can do this. The simplest is just to use the built-in QUnit "fixtures" element. In your QUnit HTML file, simply add any HTML you want in the div with the id of qunit-fixture. Any HTML you put in there will be reset to what it was on load before each test (automatically).
<html>
...
<body>
<div id='qunit'></div>
<div id='qunit-fixture'>
<!-- everything in here is reset before each test -->
<form>
<input id='userid' type='text'>
<input id='login-btn' type='submit'>
</form>
</div>
</body>
</html>
Note that the HTML in the fixture doesn't really have to match what you have in production, but obviously you can do that. Really, you should just be adding the minimal necessary HTML so that you can minimize any side effects on your tests.
The second option is to actually pull in the HTML from that login page and delay the start of the QUnit tests until the HTML loading is complete:
<html>
<head>
...
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<script>
// tell QUnit you're not ready to start right away...
QUnit.config.autostart = false;
$.ajax({
url: '/path/to/startPage.html',
dataType: 'html',
success: function(html) {
// find specific elements you want...
var elem = $(html).find(...);
$('#qunit-fixture').append(elem);
QUnit.start(); // ...tell QUnit you're ready to go
}
});
</script>
...
</head>
...
</html>
Another way to do this without using jquery is as follows
QUnit.config.autostart = false;
window.onload = function() {
var xhr = new XMLHttpRequest();
if (xhr) {
xhr.onloadend = function () {
if(xhr.status == 200) {
var txt = xhr.responseText;
var start = txt.indexOf('<body>')+6;
var end = txt.indexOf('</body>');;
var body_text = txt.substring(start, end);
var qunit_fixture_body = document.getElementById('qunit-fixture');
qunit_fixture_body.innerHTML = body_text;
}
QUnit.start();
}
xhr.open("GET", "index.html");
xhr.send();
} else {
QUnit.start(); //If getting the html file from server fails run tests and fail anyway
}
}

Categories