AngularJS component not updating value to DOM - javascript

Here is a plunkr link where i tried to create a service (factory) and a component which gets value from the service and displays on the template.
I am able to see the value reaching the controller function but then the DOM is not reflecting the values. Need help in understanding how to keep
DOM in sync with the component data.
//heroDetail.js
(function(angular) {
'use strict';
angular.module('heroApp').component('heroDetail', {
templateUrl: 'heroDetail.html',
bindings: {
hero: '='
},
controller: heroCtrl
});
heroCtrl.$inject=['mainManager'];
function heroCtrl(mainManager) {
var vm = this;
vm.$onInit = function () {
vm.hero = mainManager.hero;
alert(vm.hero.name);
}
}
})(window.angular);
//index.js
(function(angular) {
'use strict';
angular.module('heroApp', []).factory('mainManager', function mainManager() {
let hero = {
name: 'Spawn',
}
function makeSuperHero() {
hero.title = 'Super Hero';
}
return {
hero: hero
};
});
})(window.angular);
<!--index.html-->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-heroComponentSimple-production</title>
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<script src="index.js"></script>
<script src="heroDetail.js"></script>
</head>
<body ng-app="heroApp">
<!-- components match only elements -->
<div>
<b>Hero</b><br>
<hero-detail></hero-detail>
</div>
</body>
</html>
<!--HeroDetail.html-->
<span>Name: {{heroCtrl.hero.name}}</span>
Please use plunkr link since the snippet wont compile here.

Related

AngularJS + Typescript controller cant be found

I am trying to add typescript to AngularJS and I'm getting the following error
Error: [$controller:ctrlreg] The controller with the name 'MyController' is not` registered
Has anyone clue on what I am doing wrong?
I have created the following class
/// <reference path='references/_all.ts' />
var app = angular.module('shop', []);
class MyController {
constructor($scope: any) {
$scope.message = { title: "Hello World!!" };
};
}
app.controller('MyController', MyController);
and html:
<html>
<head>
...
</head>
<body ng-app="shop">
<div ng-controller="MyController">
{{message.title}}
</div>
</body>
</html>
I am using grunt to compile it:
/// <reference path='references/_all.ts' />
var app = angular.module('shop', []);
var MyController = (function () {
function MyController($scope) {
$scope.message = { title: "Hello World!!" };
};
return MyController;
})();
app.controller('MyController', MyController);
Do you have link file with app?
<script src="./app.js"></script>
Here is my solution:
var app = angular.module('shop', []);
var MyController = (function () {
function MyController($scope) {
$scope.message = { title: "Hello World!!" };
}
return MyController;
})();
app.controller('MyController', MyController);
<head>
<meta charset="utf-8" />
<title>AngularJS + Typescript controller cant be found</title>
<script src="https://code.angularjs.org/1.5.4/angular.js"></script>
<script src="./app.js"></script>
</head>
<body ng-app="shop">
<div ng-controller="MyController">
{{message.title}}
</div>
</body>
</html>

Problems with uploading a file and parsing with AngularJS

Trying to build a simple application that allows a user to upload a file, and upon clicking the 'add' button, It parses the file and displays the result within the browser.
I am using IntelliJ to generate the AngularJS application stub, and modifying it accordingly.
My attempt is below:
view1.html
<!DOCTYPE html>
<html lang="en" ng-app>
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="../app.css">
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/ng-file-upload/ng-file-upload-shim.js"></script> <!-- for no html5 browsers support -->
<script src="bower_components/ng-file-upload/ng-file-upload.js"></script>
<!--<script src="view1.js"></script>-->
</head>
<body>
<div ng-controller="View1Ctrl">
<input type="file" id="file" name="file"/>
<br/>
<button ng-click="add()">Add</button>
<p>{{data}}</p>
</div>
</body>
</html>
view1.js
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', function ($scope) {
$scope.data = 'none';
$scope.add = function() {
var f = document.getElementById('file').files[0],
r = new FileReader();
r.onloadend = function(e) {
$scope.data = e.target.result;
}
r.readAsArrayBuffer(f);
}
}]);
view1_test.js
'use strict';
describe('myApp.view1 module', function() {
beforeEach(module('myApp.view1'));
describe('view1 controller', function(){
it('should ....', inject(function($controller, $rootScope) {
//spec body
// var view1Ctrl = $controller('View1Ctrl');
var $scope = $rootScope.$new(),
ctrl = $controller('View1Ctrl', {
$scope: $scope
// $User: {}
});
expect(ctrl).toBeDefined();
}));
});
});
app.js
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
I am not sure where I could potentially be going wrong? I viewed quite a few questions to this and tried multiple different approaches but I cannot get this to work despite all of my tests passing.
The issue was around my view1.js file. I found the Papa Parse library extremely useful.
Here is my solution used from the open source Papa Parse community:
Papa.parse(fileInput[0], {
complete: function(results) {
console.log("Complete!", results.data);
$.each(results.data, function(i, el) {
var row = $("<tr/>");
row.append($("<td/>").text(i));
$.each(el, function(j, cell) {
if (cell !== "")
row.append($("<td/>").text(cell));
});
$("#results tbody").append(row);
});
}
});

ui-router not replacing ui-view in index.html

I have set up a basic AngularJS app in VS and cannot get the ui-router functionality working. I have looked at videos, blogs, SO answers and as far as I can tell I am doing everything right, although, I am brand new to web development.
First, here is the solution structure:
and the code...
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<meta charset="utf-8" />
</head>
<body ng-app="app">
<div ui-view></div>
<script src="bower_components/angular/angular.js"></script>
<script src="app/app.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
</body>
</html>
app.js:
(function () {
'use strict';
angular.module('app', ['ui.router']);
})();
app.states.js:
(function () {
'use strict';
angular.module('app')
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/test.html',
controller: 'testCtrl',
controllerAs: 'vm'
})
});
})();
test.html:
<div>
<p>TEST PAGE</p>
</div>
testCtrl.js:
(function () {
'use strict';
angular.module('app')
.controller('testCtrl', testCtrl);
testCtrl.$inject = ['$state'];
function testCtrl($state) {
var vm = this;
var userAuthenticated = false;
init();
function init() {
$state.go('home');
};
};
})();
Can anyone see anywhere I have made a mistake?
There is a working example
I would say, that I miss these lines in your index.html
...
<script src="app/app.states.js"></script>
<script src="templates/testCtrl.js"></script>
That will loade the crucial state definition, and related controller. Check it in action here

Passing method through a directive to a parent directive

edit: Modified the code as per stevuu's suggestion as well as added a plunkr to here
I'm currently attempting to have a child directive call a method(resolve) through another directive all the way up to a parent directive but I'm having difficulties identifying the problem with my approach.
The problem right now seems to be that although resolve() does get called as expected on click, selected remains undefined.
the html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Angular: directive using & - jsFiddle demo</title>
<script type='text/javascript' src='//code.jquery.com/jquery-1.9.1.js'></script>
<link rel="stylesheet" type="text/css" href="/css/normalize.css">
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<script type='text/javascript' src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<style type='text/css'>
</style>
</head>
<body ng-app="myApp">
<div grand-parent>
<span>selected: {{text}}</span>
<div parent resolve="resolve"></div>
</div>
</body>
</html>
And the js:
var myApp = angular.module('myApp',[]);
myApp.directive('grandParent', function() {
return {
scope:{
resolve: "&"
},
link: function($scope, $element) {
$scope.resolve = function(selected){
$scope.text = selected
}
}
};
});
myApp.directive('parent', function(){
return{
scope: {
resolve: "&"
},
template: "<div child resolve='resolve'></div>"
};
});
myApp.directive('child', function() {
return {
scope: {
resolve: "&"
},
template: "<div>Click me!</div>",
link: function($scope, $element) {
$element.on("click", function(){
$scope.$apply(function(){
$scope.resolve({selected: "Yahoo!!"});
});
});
}
};
});
resolve: "&" is a mapping. So here:
myApp.directive('grandParent', function() {
return {
scope:{
resolve: "&"
},
link: function($scope, $element) {
$scope.resolve = function(selected){
$scope.text = selected
}
}
};
});
you are trying to map "resolve" to ... nothing, because "grandParent" doesn't have any attr named "resolve".
If you want to share some staff betweens directives you should do something like that:
view
<div data-grand-parent resolve="resolved()">
<div data-parent ></div>
</div>
Directives
var app = angular.module('test');
app.directive('grandParent', function() {
return {
scope : {
resolve : "&" // in view we defined resolve attr
// with "resolve()" value, so now resolve=resolved()
// in grandParent scope too.
},
controller: function($scope){
this.getResolve = function(){
return $scope.resolve;
};
}
};
});
app.directive('parent', function() {
return {
require: "^grandParent",
link: function(scope, element, attr, grandParentCtrl){
grandParentCtrl.getResolve()();
},
template : ""
};
});
controller
angular.module('desktop')
.controller('MainCtrl', function ($scope, mocks) {
$scope.resolved = function(){
console.log("calling $scope.resolved() ...");
};
});
output
calling $scope.resolved() ...
So, how does it work?
We defined resolved function in our controller, then we sign this function to attr "resolve" in grandParent directive. Thx to resolve : "&" we could mapped that resolved() function to "resolve" property in grandParent scope. At the end we inject grandParent to other directives. That's all.
I recommend you to read angularJs by Brad Green, Shyam Seshadri. it's not the best book but could be worse and it's free. You can find very good tutorial too on http://www.egghead.io/
ps. Sorry for my english ;/

Angularjs app not working after adding new controller

Initially my controller.js looked like this
function MyCtrl1() {}
MyCtrl1.$inject = [];
function MyCtrl2() {
}
MyCtrl2.$inject = [];
And the html code like this
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>My AngularJS App</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="http://angular-ui.github.com/bootstrap/ui-bootstrap-tpls-0.2.0.js"></script>
<link rel="stylesheet" href="css/app.css"/>
</head>
<body>
<ul class="menu">
<li>view1</li>
<li>view2</li>
</ul>
<div ng-view></div>
<div>Angular seed app: v <span app-version></span></div>
<div>Author is : <span app-author></span></div>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
Here is the service.js code
angular.module('myApp.services', []).
value('version', '0.1')
.value('author','Jay');
And the directive.js code
angular.module('myApp.directives', []).
directive('appVersion', ['version', function(version) {
return function(scope, elm, attrs) {
elm.text(version);
};
}])
.directive('appAuthor', ['author', function(author) {
return function(scope, elm, attrs){
elm.text(author);
};
}]);
The above code worked completely worked fine and displayed version and author configured in service.js
The moment i modify my controller.js to include a new controller as below it stops working and nor the version nor the author is displayed.
The modified controller code is as below
function MyCtrl1() {}
MyCtrl1.$inject = [];
function MyCtrl2() {
}
MyCtrl2.$inject = [];
angular.module('myApp', ['ui.bootstrap']);
var TabsDemoCtrl = function ($scope) {
$scope.panes = [
{ title:"Dynamic Title 1", content:"Dynamic content 1" },
{ title:"Dynamic Title 2", content:"Dynamic content 2" }
];
};
TabsDemoCtrl.$inject = ['$scope'];
Any pointers why this thing is not working.
Looks like your problem is the redeclaration of myApp here:
angular.module('myApp', ['ui.bootstrap']);
I was able to reproduce your problem when I had
angular.module('myApp', ['myApp.services', 'myApp.directives']);
angular.module('myApp', ['ui.bootstrap']);
Switching it to
angular.module('myApp', ['myApp.services', 'myApp.directives', 'ui.bootstrap']);
made everything work again.

Categories