adding module not working - javascript

I am still in study mode of angularjs and just 2 day old. I was trying to make module and so i created seperate js file for it and created module like below.
Also added controller.
var app = angular.module("githubViewer", []);
app.controller("MainCtrl", MainCtrl);
But when i run i get error 'MainCtrl' is not a function, got undefined
here is Plunker
Can someone help me?

After looking in plunker,I think you want to create a separate module in separate file for your controllers and add it to your main module.
For that create module for controllers in separate file,
angular.module("githubViewer", [])
.controller('MainCtrl', function($scope,$http) {
//your logic
});
then add it to your main as dependency in main module
angular.module('plunker', ['githubViewer']);
here is working demo : http://plnkr.co/edit/T9p7Uo2DxUVjqS1wuuiA?p=preview

Ok, you're new to angular, so here's a couple of rules which you must follow until you can prove you need to do otherwise.
You can place definition of module in a separate file. In short plunkers it is often an overkill, but that's what you should be doing in realworld-sized apps. Note that I'm talking about only the module here. Not talking about controllers, factories and other stuff.
Separating body of controller from its inclusion into angular does not bring any benefit. Don't do that.
That said, your files should look like this:
# my_app.module.js
angular.module('myApp', []);
# main.controller.js
var app = angular.module('myApp')
app.controller('MainCtrl', MainCtrl);
function MainCtrl() {
// logic here
}

I check your Plunker.
here is Working Plunker as you want logic of controller in seperate js file and module in seperate file
app.js
function MainCtrl($scope,$http) {
var person = {
firstName: "Kiran",
lastName: "Nandedkar"
};
$scope.name = 'World';
var onUserComplete = function(response){
$scope.user = response.data;
}
var onError = function(reason){
$scope.error = "dfdfdf" ;
}
$http.get("https://api.github.com/users/odetocode")
.then(onUserComplete,onError);
$scope.person = person;
};
module.js
var app = angular.module("githubViewer", []);
app.controller("MainCtrl", MainCtrl);
index.html
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
<script src="module.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{person.firstName}}!</p>
<div>Login : {{user.login}}</div>
</body>

Related

Getting an error that secondController is not registered

Hi Im trying to write an angular app from scratch. (New to it) Keep getting an error that secondController is not registered. Why?
These are my three files and for some reason it keeps saying "The controller with the name 'secondController' is not registered."
index.html
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./angular.js"></script>
<script src="./secondModule.js"></script>
<script src="./app.js"></script>
</head>
<body>
<div ng-controller="appController">
<p>App text : {{myAppText}}</p>
<p>secondControllerModule: {{ secondControllerText }}</p>
</div>
<div ng-controller="secondController">
Second Module : {{secondControllerText}}
</div>
</body>
</html>
app.js
angular.module("myApp", [])
.controller("appController",["$scope", function($scope){
$scope.myAppText = "Hello, I am appController text"
}])
secondModule.js
angular.module("myApp", [])
.controller("secondController",["$scope", function($scope){
$scope.secondControllerText = "Hello, I am seasdfsdfasdfacond Controller Text"
}])
I think as per your code you should take three files
1. Declare angular module in module.js file
var app = angular.module("myApp", []);
Add the first controller appController.js
app.controller("appController",["$scope", function($scope){
$scope.myAppText = "Hello, I am appController text";
}]);
Add second controller file secondController.js
app.controller("secondController",["$scope", function($scope){
$scope.secondControllerText = "Hello, I am seasdfsdfasdfacond Controller Text";
}]);
now put them in this heirarchy
- Add ref of Angular JS
then
1 module.js
2 appController.js
3 secondController.js
First of all, I would like to clarify that this is incorrect:
<div ng-controller="appController">
<p>App text : {{myAppText}}</p>
<p>secondControllerModule: {{ secondControllerText }}</p>// Defined in the wrong ng-controller,
so move it to the correct one.
</div>
The reason you are getting that error is that you're defining the app module twice in your js files. It's rather simple, all you need to do is take off the second parameter in your secondModule.js
angular.module("myApp")// Needs to be like this
.controller("secondController",["$scope", function($scope){
$scope.secondControllerText = "Hello, I am seasdfsdfasdfacond Controller Text"
}])
Then in your app.js file
angular.module("myApp", [])
.controller("appController",["$scope", function($scope){
$scope.myAppText = "Hello, I am appController text"
}])
Then in your HTML file, you need to fix the order of the script
<script src="./angular.js"></script>
<script src="./app.js"></script> // App module must be first because the module is defined here
<script src="./secondModule.js"></script>

angularjs firebase showing value in log but not in actual html

I hope this isn't gonna be too broad.
I have this simple angular website where I show data from firebase (...)
I fetch my data this way in the .js file:
'use strict';
angular.module('webApp.seeHoraire', ['ngRoute', 'firebase'])
.config(['$routeProvider', function($routeProvider){
$routeProvider.when('/seeHoraire', {
templateUrl: 'seeHoraire/seeHoraire.html',
controller: 'SeeHoraireCtrl'
});
}])
.controller('SeeHoraireCtrl', ['$scope', 'CommonProp', '$firebaseArray', function($scope, CommonProp, $firebaseArray){
var userId = firebase.auth().currentUser.uid;
console.log('Current user uid : ', userId);
return firebase.database().ref('/Users/' + userId + '/Horaire').once('value').then(function(snapshot) {
var lun1 = (snapshot.val() && snapshot.val().lun1) || 'X';
$scope.lun1 = lun1;
console.log($scope.lun1);
})
}])
This is logging me my "lun1" value perfectly fine, but when it comes to displaying it in my .html file, it shows nothing!
My .html file:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="seeHoraire/seeHoraire.css" />
</head>
<body ng-controller="SeeHoraireCtrl">
<h1>{{lun1}}</h1>
</body>
</html>
Maybe I forgot something? Please help me.
Have a good day.
Maybe try:
$scope.$apply(function(){
$scope.lun1=lun1;
});
This was copied from: this link. Other answers there may also be helpful.

How to get data from rest api which has basic authentication?

I'm trying to get data from this website through HTTP get method. This website has basic authentication. The data is in JSON format.
This is the rest api website:
(https://shoploapi.herokuapp.com/sellers)
// Code goes here
angular.module('myapp', ['myapp.controller']);
angular.module('myapp.controller', ['myapp.service'])
.controller('testController', function($scope, testService) {
$scope.posts = {};
function GetAllPosts() {
var getPostsData = testService.getPosts();
getPostsData.then(function(post) {
$scope.posts = post.data;
}, function() {
alert('Error in getting post records');
});
}
GetAllPosts();
});
angular.module('myapp.service', [])
.service('testService', function($http) {
//get All NewsLetter
this.getPosts = function() {
return $http.get('https://shoploapi.herokuapp.com/sellers');
};
});
angular.module('myApp', ['base64'])
.config(function($httpProvider, $base64) {
var auth = $base64.encode("bhupendra7:ice123age456");
$httpProvider.defaults.headers.common['Authorization'] = 'Basic ' + auth;
});
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-base64/2.0.5/angular-base64.js"></script>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body ng-app="myapp">
<h1>Hello Plunker!</h1>
<div ng-controller="testController">
<div>
<ul>
<li ng-repeat="post in posts">
{{post.careof}} {{post.district}} {{post.gender}} {{post.name}}
</li>
</ul>
</div>
</div>
</body>
</html>
Here's the link to my Plunker:
(https://plnkr.co/edit/7pqljm?p=preview)
Can anyone help?
There are 2 problems in your code.
1. You have a typo
In angular.module('myApp', ['base64']), change to module name to myapp
2. The way you have injected your myapp.controller to myapp module
Change it to angular.module('myapp', []); You will also need to reorder your code. Check out the Plunker I have created for you.
Even if you fix the above two problems, you will still face a CORS problem from Heroku. Depending on your server-side technology (NodeJS, Rails etc.), you will need to enable it from the server to be able to communicate with your app. You can also look in to JSONP with AngularJS
Hope this helps

DI in directive results in unknown somethingProviderProvider

I know that AngularJS appends "Provider" to registered providers, so it is not necesary to name them with that "provider" and you should call them with the full name as "SomethingProvider".
I'm doing that but the console throws me an
Unknown provider: ReportProviderProvider <- ReportProvider <- reportDirective
I have a service, provider and directive called Report, everyone in its own file. ReportProvider.js, ReportService.js, ReportDirective.js
When I try to use the directive I got the error.
Why do angular appends "Provider" to my required dependency?
angular.module('thdmaterialApp')
.provider('Report', function () {});
angular.module('thdmaterialApp')
.service('Report', function (ReportProvider) {
});
angular.module('thdmaterialApp')
.directive('report', function (ReportProvider) {} );
you don't need to write it like this ReportProvider ,, you just need to inject Report ,,
you will have to add Provider when you want to use it in config ,, but in DI it works as other injectable services ,,
and I think of course you will need to change the name of Report service ,,
You are trying to inject a the provider into your directive? I think they are only meant to be used inside config blocks to pre-configure a service. From the docs:
You should use the Provider recipe only when you want to expose an API
for application-wide configuration that must be made before the
application starts. This is usually interesting only for reusable
services whose behavior might need to vary slightly between
applications.
Also, I think your provider will need to define this.$get as a function that returns an object for it to work.
You only need to use provider if you want to be able to change some properties on a service in some situations. I've tried to show this in a DEMO you might find helpful.
app.js
var app = angular.module('thdmaterialApp', []);
app.controller('MainCtrl', function($scope, ReportService, Report) {
$scope.serviceValue = ReportService.value;
$scope.value = Report.getValue();
});
app.provider('Report', function () {
// if you remove the config block you should see this value
this.value = 'default';
this.configureValue = function(newValue){
this.value = newValue;
}
this.$get = function() {
var value = this.value;
return {
getValue: function() {
return value
}
}
};
});
// if you comment this out then the default value will be returned
app.config(function(ReportProvider){
ReportProvider.configureValue('new configured value');
});
app.service('ReportService', function () {
return {
value: 'I don\'t need to be configured.'
};
});
index.html
<!DOCTYPE html>
<html ng-app="thdmaterialApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>ReportService.value: {{serviceValue}}</p>
<p>Report.getValue(): {{value}}</p>
</body>
</html>

Multiple Angularjs Applications (Driving Portlets)

I have a use case that requires the loading of separate angular applications.
Based on several stack overflow questions and this google thread, it's doable. However, I can't get it to work.
Looking at the documentation:
http://docs.angularjs.org/api/angular.bootstrap
It looks like you need to provide the element (what is the right way to get a handle on the element?), and then how to tie it back to config, controllers, etc. And how would this work with routes? IE how does collision work, ie app a and app b map /foo to /fooa.html and /foob.html respectively... or each app describes its own .otherwise?
Thanks!
So given the requirement that this be a service driven content the only way I can see to do this is kind of a mix between angular and standard html practices. Effectively you'll want to take a page from the plunker book and use Iframes to contain each individual portlet.
<!doctype html> <html lang="en">
<body ng-app="plunker" ng-controller="MainCtrl">
<!-- define foo -->
<div>
<ul class="menu">
<li>foo1</li>
<li>foo2</li>
</ul>
<iframe seamless="true" ng-src="foo.index.html{{fooRoute}}"></iframe> </div>
<div>
<ul class="menu">
<li>bar1</li>
<li>bar2</li>
</ul>
<iframe seamless="true" ng-src="bar.index.html{{barRoute}}"></iframe> </div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script> <script src="app.js"></script> </body> </html>
Then on each of these portlets you'll want to have a completely separate application (including the loading of resources).
<!doctype html>
<html lang="en">
<body ng-app="fooApp">
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script>
var app = angular.module('fooApp', ['fooApp.controllers']);
// Configure the app
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/foo1', {template: '<h1>Foo</h1><h2>foo1</h2>', controller: 'MyCtrl1'});
$routeProvider.when('/foo2', {template: '<h1>Foo</h1><h2>foo2</h2>', controller: 'MyCtrl2'});
}]);
angular.module('fooApp.controllers', []).
controller('MyCtrl1', [function () {
console.log("fooApp.MyCtrl1 invoked.");
}])
.controller('MyCtrl2', [function () {
console.log("fooApp.MyCtrl2 invoked.");
}]);
</script>
</body>
</html>
This is a little less efficient for loading than utilizing a common application base but at the moment this isn't feasible. There is talk at the angular-ui's ui-router team about controlling independent views which may be a workable solution for you but it is currently not implemented, you can follow the discussion at https://github.com/angular-ui/ui-router/issues/84 and chime in with your need. There is also now an issue specifically for this on the ui-router issues list at https://github.com/angular-ui/ui-router/issues/160.
Working plunker of this design: http://plnkr.co/edit/sPoK3I?p=preview
Ok so I figured out how to do this using the angular ui-router the key comes down to the ability of the angular ui-router to transition states without effecting the URL.
The steps to get this working
First instantiate each application as a stand alone application using
a manual bootstrap to an ID'd element.
Attach the ui-router $stateProvider to each application to drive the internal state transitions (routes).
You must leave off the url key here for each defined state or you'll reset the page by changing the url on each state transition.
Setup a state function in a main controller to drive state changes.
The following is the code to get this working:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.0.x" src="http://code.angularjs.org/1.0.7/angular.min.js" data-semver="1.0.7"></script>
<script src="angular-ui-states.min.js"></script>
<script src="app.js"></script>
</head>
<!-- define foo -->
<div id="fooApp" ng-controller="MainCtrl">
<ul class="menu">
<li>foo1</li>
<li>foo2</li>
</ul>
<div ui-view>
</div>
</div>
<script>
// Declare app level module which depends on filters, and services
var app = angular.module('fooApp', ['fooApp.controllers', 'ui.state']);
// Configure the app
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('foo1',
{
template: '<h1>Foo</h1><h2>foo1</h2>',
controller: 'MyCtrl1'
})
.state('foo2',
{
template: '<h1>Foo</h1><h2>foo2</h2>',
controller: 'MyCtrl2'
});
}]);
angular.module('fooApp.controllers', [])
.controller('MainCtrl', ['$scope', '$state', function($scope, $state){
$scope.state = function(name){
console.log('Transition to state ' + name);
$state.transitionTo(name);
}
}])
.controller('MyCtrl1', [function () {
console.log("fooApp.MyCtrl1 invoked.");
}])
.controller('MyCtrl2', [function () {
console.log("fooApp.MyCtrl2 invoked.");
}]);
// manually bootstrap
var div = document.getElementById('fooApp');
console.log(div);
angular.bootstrap(div, ['fooApp']);
</script>
<!-- define bar -->
<div id="barApp" ng-controller="MainCtrl">
<ul class="menu">
<li>bar1</li>
<li>bar2</li>
</ul>
<div ui-view>
</div>
</div>
<script>
// Declare app level module which depends on filters, and services
var app = angular.module('barApp', ['barApp.controllers', 'ui.state']);
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('bar1',
{
template: '<h1>Bar</h1><h2>bar1</h2>',
controller: 'MyCtrl1'
})
.state('bar2',
{
template: '<h1>Bar</h1><h2>bar2</h2>',
controller: 'MyCtrl2'
});
}]);
angular.module('barApp.controllers', [])
.controller('MainCtrl', ['$scope', '$state', function($scope, $state){
$scope.state = function(name){
console.log('Transition to state ' + name);
$state.transitionTo(name);
}
}])
.controller('MyCtrl1', [function () {
console.log("barApp.MyCtrl1 invoked.");
}])
.controller('MyCtrl2', [function () {
console.log("barApp.MyCtrl2 invoked.");
}]);
// manually bootstrap
var div = document.getElementById('barApp');
console.log(div);
angular.bootstrap(div, ['barApp']);
</script>
</body>
</html>
Working plunker of this solution at http://plnkr.co/edit/bXSN8qSMdioZJLYs2zyk?p=preview
Please see my previous answer for a discussion currently occurring to make portlet support more intrinsic in the ui-router.
Figured it out. Here's how to successfully load two angular applications in parallel. Also see that I named the controllers the same for each app to show that dependencies will not collide (since they are scoped within each respective app via module):
<!doctype html>
<html lang="en">
<body>
<script src="lib/angular/angular.js"></script>
<!-- define foo -->
<div id="fooApp">
<ul class="menu">
<li>foo1</li>
<li>foo2</li>
</ul>
<div ng-view>
</div>
</div>
<script>
// Declare app level module which depends on filters, and services
var app = angular.module('fooApp', ['fooApp.controllers']);
// Configure the app
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/foo1', {template: '<h1>Foo</h1><h2>foo1</h2>', controller: 'MyCtrl1'});
$routeProvider.when('/foo2', {template: '<h1>Foo</h1><h2>foo2</h2>', controller: 'MyCtrl2'});
}]);
angular.module('fooApp.controllers', []).
controller('MyCtrl1', [function () {
console.log("fooApp.MyCtrl1 invoked.");
}])
.controller('MyCtrl2', [function () {
console.log("fooApp.MyCtrl2 invoked.");
}]);
// manually bootstrap
var div = document.getElementById('fooApp');
console.log(div);
angular.bootstrap(div, ['fooApp']);
</script>
<!-- define bar -->
<div id="barApp">
<ul class="menu">
<li>bar1</li>
<li>bar2</li>
</ul>
<div ng-view>
</div>
</div>
<script>
// Declare app level module which depends on filters, and services
var app = angular.module('barApp', ['barApp.controllers']);
// Configure the app
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/bar1', {template: '<h1>Bar</h1><h2>bar1</h2>', controller: 'MyCtrl1'});
$routeProvider.when('/bar2', {template: '<h1>Bar</h1><h2>bar2</h2>', controller: 'MyCtrl2'});
}]);
angular.module('barApp.controllers', []).
controller('MyCtrl1', [function () {
console.log("barApp.MyCtrl1 invoked.");
}])
.controller('MyCtrl2', [function () {
console.log("barApp.MyCtrl2 invoked.");
}]);
// manually bootstrap
var div = document.getElementById('barApp');
console.log(div);
angular.bootstrap(div, ['barApp']);
</script>
</body>
</html>
The only remaining question is how to deal with routing collisions.
Well you have 2 choices here:
if you create them as angular.module() there would not be a way atm to connect the modules with each other.
if you create directives with a templateURL to lazyload your components you could broadcast shared attributes and listen to them and you could use the same services in your app.
Probably that would be the best for you.

Categories

Resources