I am trying to load dynamic links from the json to into my iframe template. When I load the iframe page, this error pops up. I don't really know why. This is the first time I've seen this error. Here is the code below.
Controller
app.controller('apps', [
'$scope',
'$http',
'contentService',
'gotoService',
'getIndex',
'$routeParams', function($scope, $http, contentService, gotoService, getIndex, $routeParams){
contentService.then(function(data){
$scope.data = data; // access all data
$scope.appsList = $scope.data.appsList; // list of shortcuts
// change url to links
$scope.goTo= function(url){
gotoService.getLink(url);
}
// get index
$scope.getIndex = function(index){
getIndex.current(index);
}
// embed in iframe
$scope.link = function(){
$scope.indexRoute = $routeParams.index;
return $scope.appsList[$scope.indexRoute].url;
}
});
}]);
iframe template
<iframe ng-controller="apps" ng-src="{{link()}}" width="800" height="600">
</iframe>
apps icon template
<div class="apps-background" ng-click="goTo(a.link+'/'+$index); getIndex($index);" ng-style="{'background-image':'url({{a.image}})', 'background-repeat': 'no-repeat', 'background-size': 'cover'}">
You can't have interpolation directive inside a ng-style directive expression, you need to correct it like below.
<div class="apps-background"
ng-click="goTo(a.link+'/'+$index); getIndex($index);"
ng-style="{'background-image': 'url('+ a.image + ')', 'background-repeat': 'no-repeat', 'background-size': 'cover'}">
Similar answer
I fixed the problem. I changed the code in my controller to this and it worked perfectly.
app.controller('apps', [
'$scope',
'$http',
'contentService',
'gotoService',
'getIndex',
'$routeParams',
'$sce', function($scope, $http, contentService, gotoService, getIndex, $routeParams, $sce){
contentService.then(function(data){
$scope.data = data; // access all data
$scope.data = data; // access all data
$scope.appsList = $scope.data.appsList; // list of shortcuts
// change url to links
$scope.goTo= function(url){
gotoService.getLink(url);
}
// get index
$scope.getIndex = function(index){
getIndex.current(index);
}
// embed in iframe
$scope.link = function(){
$scope.indexRoute = $routeParams.index;
return $sce.trustAsResourceUrl($scope.appsList[$scope.indexRoute].url);
}
});
}]);
Related
Im new to angular js and im not able to figure out how to change the child controller scope variable from parent controller. Here is the code snippet for that:
var mainApp = angular.module("mainApp", []);
var parentCtrl = function($rootScope, $scope, shareService, $log){
shareService.setDetails($scope.pdetails);
}
var mainCtrl1 = function($rootScope, $scope, shareService, $log){
$scope.msg = "Controller 1";
$scope.details = shareService.details;//shareService.details;
}
var mainCtrl2 = function($rootScope, $scope, shareService){
$scope.msg = "Controller 2";
$scope.details = shareService.details;//shareService.details;
}
parentCtrl.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainCtrl1.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainCtrl2.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainApp.controller("parentController", parentCtrl)
.controller("mainController1", mainCtrl1)
.controller("mainController2", mainCtrl2)
.factory("shareService", function(){
var shareData = {
details : "sadfgs detaisdfadsfasdf..",
setDetails: function(value){
this.details = value;
}
};
return shareData;
});
<html>
<head>
<title>Angular JS Views</title>
<script src='lib/angular.js'></script>
<script src='js/mainApp.js'></script>
<script src='js/studentController.js'></script>
</head>
<body ng-app = 'mainApp' ng-controller='parentController' ng-strict-di>
<div ng-controller='mainController1'>
1. Msg : {{msg}}<br/>
Share Details: {{details}}<br/><br/>
</div>
<div ng-controller='mainController2'>
2. Msg : {{msg}}<br/>
Share Details: {{details}}<br/><br/>
</div>
<input type='text' ng-model='pdetails'/>
</body>
</html>
Here is the Plunker link:
https://plnkr.co/edit/hJypukqMmdHSEZMVnkDO?p=preview
In order to change value of child controller from parent controller you can use $broadcast on $scope.
syntax
$scope.$broadcast(event,data);
$broadcast is used to trigger an event(with data) to the child scope from current scope.
In child controller use $on to receive the event(with data).
Here id the code snippet:
app.controller("parentCtrl",function($scope){
$scope.OnClick=function()
{
$scope.$broadcast("senddownward",$scope.messege);
}
});
app.controller("childCtrl",function($scope){
$scope.$on("senddownward",function(event,data)
{
$scope.messege=data;
});
});
In this example I am broadcasting the event on ng-click,you can use some other custom event.like $watch on $scope.
See this example
https://plnkr.co/edit/efZ9wYS2pukE0v4JsNCC?p=preview
P.S. you can change the name of event from senddownward to whatever you want
You can access the parent's scope properties directly due to the scope inheritance:
<div ng-controller='mainController1'>
Share Details: {{pdetails}}
</div>
Your example does not work because the controllers get executed only once before the view is rendered, pdetails is empty at that moment.
To monitor the changes to pdetails, you can use $watch in the child controller:
$scope.$watch('pdetails', function(newVal) {
$scope.details = newVal;
});
I've been learning Angular recently and in the process of creating a new website referenced I created with a tutorial. Following all the steps I was told, for some reason I am getting this error. And strangely, it is showing up as some sort of url. Here's the "error":
http://errors.angularjs.org/1.4.9/ng/areq?p0=PostCtrl&p1=not%20a%20function%2C%20got%20undefined
Removing all the url gibberish leaves PostCtrl not a function got undefined.
I don't understand why, I've looked all over Stack Overflow and all the common errors such as using global scope, not registering the controller, and other common errors don't seem to be the cause. Here is the controller and jade file.
Controller:
var app = angular.module("app", []);
(function() {
var PostCtrl = function ($scope, $log, $location) {
$scope.posts = [];
$scope.post = function (title, content) {
$scope.title = title;
$scope.content = content;
$log.info("Posting article: " + title + "\n" + content);
$scope.posts.push([title, content]);
};
};
app.controller("PostCtrl", ["$scope", "$log", PostCtrl]);
})();
Jade file: (ng-app="app") is inside the layout file, along with all other scripts involving angular.
extends partials/layout
block scripts
script(src="app/controllers/PostCtrl.js")
block content
.body(ng-controller="PostCtrl")
.row
.col-xs-12
form(class="form-horizontal" ng-submit="post(title, content)")
.form-group
label(for="inputTitle" class="col-sm-2 control-label") Title
.col-sm-10
input(type="text" class="form-control" id="inputTitle" placeholder="Title" ng-model="title")
.form-group
label(for="inputContent" class="col-sm-2 control-label") Content
.col-sm-10
textarea(class="form-control" id="inputContent" placeholder="Content" ng-model="content")
.form-group
.col-sm-offset-2.col-sm-10
button(type="submit" class="btn btn-default") Post
hr
.row
.col-xs-12
#FlorianTopf saved the day. I was not including $location as a dependency. New PostCtrl controller:
(function() {
var PostCtrl = function ($scope, $log, $location) {
$scope.posts = [];
$scope.post = function (title, content) {
$scope.title = title;
$scope.content = content;
$log.info("Posting article: " + title + "\n" + content);
$scope.posts.push([title, content]);
};
};
app.controller("PostCtrl", ["$scope", "$log", "$location", PostCtrl]);
})();
You are initiating twice the controller. Remove it from the html .body(ng-controller="PostCtrl")
Newbie Question
Have been watching this great Angular Beginners course but got stuck in the register process.
Code project (plnkr.co)
index.html
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="github.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ countdown }}
<form name="searchUser" ng-submit="search(username)">
<input type="search" required placeholder="Username to find" ng-model="username"/>
<input type="submit" value="Search">
</form>
<div ng-include="'userdetails.html'" ng-show="user"> </div>
</body>
</html>
github.js
(function() {
var github = function($http) { // requires the service $http
// Private implementation details //
var gettingUser = function(username) {
return $http.get("https://api.github.com/users/" + username)
.then(function(response) {
return response.data;
});
/* returning the promise that already comes with
the function to perform the data extration
*/
};
var gettingRepos = function(user) {
return $http.get(user.repos_url)
.then(function(response) {
return response.data;
});
/* returning a promise that it will return the data
- so the controller doesn't have to. */
};
// Public API //
return {
gettingUser: gettingUser,
gettingRepos: gettingRepos
};
// returns an object (github service)
};
var module = angular.module("githubViewer");
/* Not creating a module, just getting the reference
to the one created in script.js So no need to list
the dependencies in a list after githubViewer*/
// Register the Service
module.factory("$github", github);
}());
script.js
(function() {
var app = angular.module("githubViewer", []);
var MainController = function(
$scope, $github, $interval, $log,
$anchorScroll, $location) {
var onUserComplete = function(data) {
$scope.user = data;
$github.gettingRepos($scope.user)
.then(onRepos, onError);
};
var onRepos = function(data){
$scope.repos = data;
$anchorScroll( $location.hash("userDetails") );
}
var onError = function(reason) {
$scope.error = "Could not fetch data";
};
var decrementCountdown = function(){
$scope.countdown -= 1;
if($scope.countdown < 1){
$scope.search($scope.username);
}
}
$scope.search = function(username) {
$log.info("Searching for "+ username);
$github.gettingUser(username).then(onUserComplete, onError);
if(countdownIntervalObj){
$interval.cancel(countdownIntervalObj);
$scope.countdown = null;
}
};
var countdownInterval = null;
var startCountdown = function(){
countdownIntervalObj = $interval(decrementCountdown, 1000, $scope.countdown);
}
$scope.username = "angular";
$scope.message = "GitHub Viewer";
$scope.repoSortOrder = "-stargazers_count";
$scope.countdown = 5;
startCountdown();
};
app.controller("MainController",
["$scope", "$http", "$interval", "$log", "$anchorScroll", "$location", "$github", MainController]);
}());
The console keeps saying that the $github.gettingUser is not a function. What am I doing wrong?
Watch out for the order when you inject your dependencies as you are injecting seven but just passing six to the controller in the wrong order. You need to pass $http and put $github at the end.
var MainController = function($scope, $http, $interval, $log, $anchorScroll, $location, $github)
app.controller("MainController", ["$scope", "$http", "$interval", "$log", "$anchorScroll", "$location", "$github", MainController]);
When you inject resources into your controller
app.controller("MainController", ["$scope", "$http", "$interval", "$log", "$anchorScroll", "$location", "$github", MainController]);
order et type must match your controller function declaration
var MainController = function(
$scope, $github, $interval, $log,
$anchorScroll, $location) {
So here what $github contains is the $http module :)
Here is a corrected version of your plunkr
http://plnkr.co/edit/9UyNHDKiXDZAZt8PPEPy?p=preview
However I prefer this syntax, I find it more clear: http://plnkr.co/edit/byhQ7ST8AZlQ6oMYIMeV?p=preview
You should take a look to https://github.com/johnpapa/angular-styleguide
A styleguide were using at work, filled with best practices.
Have fun with angular
because the order of providers are not the same in the array ["scope", "github", etc] with the controller's. your service corresponds to another provider which is minified, even if it is not, it does not matter. you have to pass the injectors in the same order you define in the provider array
I'm having issues with a dynamically placed template.
My HTML for index.html looks something like this:
<body data-ng-controller="MainController">
<data-ng-include id="outside" src="dynamicTemplate()"></data-ng-include>
</body>
The index.html page displays a template based on a certain condition.
Here is the code for my home.html, which is the default template for index.html.
<span data-ng-bind="message" data-ng-style="messageStyle"></span>
<form data-ng-controller="FormController" data-ng-submit="processForm()">
other form stuff goes here
</form>
My FormController looks something like this:
app.controller("FormController", ['$scope', '$http', '$window', function($scope, $http, $window) {
$scope.message = "";
$scope.processForm = function() {
$scope.message = "Processing form";
$scope.messageStyle = {
"color": "green"
};
// Ajax Logic to process form
.success(function(data) {
$scope.message = data.msg; /* Message never gets updated in the view */
});
};
}]);
The issue here is that the $scope.message never displays any data in the data-ng-bind="message" after the FormController gets called. I think the issue lies with the scope not knowing which controller it belongs to. How can I fix this?
<div ng-app="myapp" ng-controller="hello">
<script>
function Hello($scope, $http) {
$http.get('http://rest-service.guides.spring.io/greeting').
success(function(data) {
$scope.greeting = data;
});
}
</script>
and I would like to print the content like this {{greeting.id}}.
the code snippet is going to get data in JSON format from "http://rest-service.guides.spring.io/greeting" using angularjs. This isn't working in eclipse. Any ideas to make it work ?
I'm fairly certain that the value of ng-controller is case sensitive.
So, this:
ng-controller="hello"
will look for a function with the name: hello, not Hello.
Here is a plunker demonstrating the issue.
Change your controller code like this.
(function () {
var myApp = angular.module('myModule');
myApp.controller('hello', ['$scope', '$http', function ($scope, $http) {
$http.get("http://rest-service.guides.spring.io/greeting").then(function(data){
$scope.greeting=data;
});
}]);
})();
and in the html
{{greeting.data.id}}
I checked it in plunker. It is working fine