I am learning AngularJS from AngularJS.org video tutorials but when I run my code it says
Error: [ng:areq] Argument 'ReviewController' is not a function
I got undefined in my console but my code looks the same as in the video here is my html
<!doctype html>
<html ng-app="store">
<title>Testing AngularJS</title>
<head>
<link rel="stylesheet" type="text/css" href="bootstrap.css"/>
<script type="text/javascript" src="js/angular.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-controller="StoreController as store">
<ul class="list-group">
<li class="list-group-item" ng-repeat="product in store.products">
<h3>{{product.name}}
<em class="pull-right">{{product.price | currency}}</em>
<img class="gallery" ng-src="{{product.images[0].full}}"/>
</h3>
<section ng-controller="PanelController as panel">
<ul class="nav nav-pills">
<li ng-class="{active: panel.isSelected(1)}"><a href ng-click="panel.selectTab(1)">Description</a></li>
<li ng-class="{active: panel.isSelected(2)}"><a href ng-click="panel.selectTab(2)">Specifications</a>
</li>
<li ng-class="{active: panel.isSelected(3)}"><a href ng-click="panel.selectTab(3)">Reviews</a></li>
</ul>
<div class="panel" ng-show="panel.isSelected(1)">
<h3> Description</h3>
<h4>{{product.description}}</h4>
</div>
<div class="panel" ng-show="panel.isSelected(2)">
<h3> Specifications</h3>
<blockquote>None yet</blockquote>
</div>
<div class="panel" ng-show="panel.isSelected(3)">
<h3> Reviews</h3>
<blockquote ng-repeat="review in product.reviews">
<b>Stars: {{review.stars}}</b>
<p>{{review.body}}</p>
<cite>_{{review.author}}</cite>
</blockquote>
<form name="reviewForm" ng-controller="ReviewController as reviewCtrl">
<blockquote>
<b>Stars: {{reviewCtrl.review.stars}}</b>
<p>{{reviewCtrl.review.body}}</p>
<cite>_{{reviewCtrl.review.author}}</cite>
</blockquote>
<label for="select">Select</label>
<select id="select" ng-model="reviewCtrl.review.stars">
<option value="1">1 star</option>
<option value="2">2 star</option>
<option value="3">3 star</option>
</select>
<label for="comments"></label>
<textarea id="comments" ng-model="reviewCtrl.review.body"></textarea>
<label for="email">Email</label>
<input ng-model="reviewCtrl.review.author" type="email" id="email"/>
<input type="submit" value="Submit"/>
</form>
</div>
</section>
</li>
</ul>
</body>
</html>
Here is my app.js file
(function () {
var app = angular.module('store', []);
app.controller('StoreController', function () {
this.products = [
{
name: 'Cup',
price: 2.95,
description: 'It is the best Buy it fast',
images: [
{
full: 'gem.jpeg'
}
],
reviews: [
{
stars: 5,
body: 'This is the best gem',
author: 'dadsa#dasasd.com'
},
{
stars: 1,
body: 'easily broken',
author: 'zzzfasdaadsa#dasasd.com'
}
]
},
{
name: 'Bottle',
price: 1.12,
description: 'It\'s the best bottle',
images: [
{
full: 'gem.jpeg'
}
],
reviews: [
{
stars: 2,
body: 'Latest gem',
author: 'aasdsa#dasasd.com'
}
]
}
]; // product is the property of the controller
});
app.controller("ReviewController", function () {
this.review = {};
});
app.controller("PanelController", function () {
this.tab = 1;
this.selectTab = function (setTab) {
this.tab = setTab;
};
this.isSelected = function (checkTab) {
return this.tab === checkTab;
};
});
})();
The problem is here:
<script type="text/javascript" src="js/angular.js"></script>
<script type="text/javascript" src="app.js"></script>
Scripts are executed in the order that they are encountered on the page. So angular.js runs before app.js. It will parse the document and try to resolve ng-app (and thereby ng-controller) before app.js has a chance to execute.
There are two easy ways to solve this:
Put app.js inline at the end of your document
Although I did say that scripts are executed in the order they are encountered, angularjs puts its initialization code behind document.isready. It's loaded, so you will have access to angular.module, but it won't execute its bootstrap logic until after your own code has finished loading. This solution is fine for tiny projects, but isn't great when your code grows large.
Bootstrap your application manually
Remove the ng-app="store" from your html code, and at the end of app.js, you will add the following code
angular.element(document).ready(function() {
angular.bootstrap(document, ['store']);
});`
If you work with angular long enough, you will get very used to this second solution, as it helps us play nicely with dynamic loaders such as $script, RequireJS, et al -- not to mention the very example you've posted!
Related
i should get output like that in second div i should get inplace of headers i should get income which is mentioned in the controller object data
I just need different content in two div when I changed the data in controller object it should be reflected in div.
here is my html code
<!DOCTYPE html>
<html ng-app="myApp">
<head>
***emphasized text***
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="angular-gridster.min.css"></link>
<link rel="stylesheet" href="wid.css"></link>
</head>
<body ng-controller="myController" >
<div gridster ng-controller="myCtrl" >
<ul>
<li gridster-item="item" ng-repeat="item in Items">
<div my-widget ></div>
</li>
</ul>
</div>
</body>
</html>
my script goes here which contains the controller as well as directive.
var app=angular.module('myApp',['gridster'])
app.controller('myController',function($scope){
$scope.Items = [
{ sizeX: 2, sizeY: 1, row: 0, col: 0, },
{ sizeX: 2, sizeY: 1, row: 0, col: 0, }
]
});
app.controller('myCtrl',function($scope){
$scope.content=[{
data:54565463,
right:67566,
title:'headers'},
{ data:65476756,
right:123,
title:"Income",
}]
});
app.directive('myWidget',function(){
return{
restrict:"EA",
scope:{
title:'#',
data:'=',
},
templateUrl:'spare.html',
}
});
and my spare html is below -
<span ng-controller="myCtrl">
<div class="panel-body " ng-style = "myStyle">
<h1 class="title" >{{content.title}}</h1>
<i class="fa fa-dollar" ></i>{{content.data}}</div>
<p id="rightcorner" ><i class="fa fa-level-up"></i>{{content.right}}
</p>
</span>
what i need is in 2 div's i should get separate data which is giveenter code heren in controller object
Your directive is using an isolated scope (scope:{ title:'#', data:'='}). That's why it doesn't have access to the content array of the parent scope (which is a good thing in general).
What you wanna do is to pass an item of $scope.content to the my-widget directive.
You could use the $index variable of the ngRepeat scope.
<li gridster-item="item" ng-repeat="item in Items">
<div my-widget data="content[$index]"></div>
</li>
As the my-widget directive has its own scope, you have to change the binding expressions (there is no thing called content in the directive scope).
<div class="panel-body">
<h1 class="title" >{{title}}</h1>
<i class="fa fa-dollar" ></i>{{data.data}}
</div>
<p id="rightcorner"><i class="fa fa-level-up"></i>{{data.right}}
</p>
By the way, title is a bad name for an attribute, as it's an html attribute.
EDIT: Added example code for a solution with a single controller, as asked in comments.
angular.module('app', [])
.controller('myController', myController)
.directive('myWidget', myWidget);
function myController() {
var vm = this;
vm.items = [
{
title: "1",
obj: { data: 123 }
},
{
title: "2",
obj: { data: 234 }
}];
}
function myWidget() {
return {
scope: {
data: '<'
},
template: '<div>Widget: {{data.data}}</div>'
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<div ng-app="app" ng-controller="myController as $ctrl" >
<div>
<ul>
<li ng-repeat="item in $ctrl.items">
<div ng-bind="item.title"></div>
<div my-widget data="item.obj"></div>
</li>
</ul>
</div>
</div>
I am new in AngularJS but I have basic HTML and JavaScript knowledge.
I have a list of links on page, and a search box. I want to filter list elements dynamically according to the text typed in the box. I have found some example but they use external lists- not a list typed on same html file.
Exactly this: https://code.ciphertrick.com/demo/angularajaxsearch/
As you guess I cannot make filtered elements visible/unvisible like this. How can I filter them (all html codes must be in 1 page so we cannot call another js file, controller or etc.)
<!DOCTYPE html>
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div class="bar">
<input type="text" class="search" ng-model="searchString" />
</div>
<ul class="data-ctrl">
<li ng-repeat="i in berkay | searchFor:searchString">
</li>
</ul>
<ul name="berkay">
<li>google</li>
<li>bbc</li>
<li>microsoft</li>
</ul>
</body>
</html>
Note: If there is a way with just Javascript or etc. without using angular js, it is welcome as well.
Last Edit: All 3 answers are correct and working fine right now.
Could you try this. I hope it works for you :)
<!DOCTYPE html>
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $filter) {
$scope.searchString=[{Text:"https://google.com"},{Text:"https://bbc.com"},{Text:"https://microsoft.com"}];
$scope.searchString2=$scope.searchString;
$scope.$watch('search', function(val)
{
$scope.searchString= $filter('filter')($scope.searchString2, val);
});
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="bar">
<input type="text" class="search" ng-model="search" />
</div>
<ul>
<li ng-repeat="item in searchString">
<a href="{{item.Text}}">{{item.Text}}</>
</li>
</ul>
</div>
</body>
</html>
Please check this updated answer. It will redirect when you click on it.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var app = angular.module("app", []);
app.controller("myCtrl", function($scope) {
$scope.berkay = [{
name: "google",
link: 'https://google.com'
}, {
name: "bbc",
link: 'https://bbc.com'
}, {
name: "microsoft",
link: 'https://microsoft.com'
}];
});
</script>
<div ng-app="app" ng-controller="myCtrl">
<div class="bar">
<!--
1. If you want to search everything(both link and name), just use searchString
<input type="text" class="search" ng-model="searchString">
2. If you want to search only name change searchString to searchString.name
<input type="text" class="search" ng-model="searchString.name">
3. If you want to search only link change searchString to searchString.link
<input type="text" class="search" ng-model="searchString.link">
-->
<input type="text" class="search" ng-model="searchString" />
</div>
<ul class="data-ctrl">
<li ng-repeat="i in berkay | filter:searchString">
{{i.name}}
</li>
</ul>
</div>
You can add javascript inside HTML itself
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var app = angular.module("app", []);
app.controller("myCtrl", function($scope) {
$scope.berkay = [{
name: "google",
link: 'https://google.com'
}, {
name: "bbc",
link: 'https://bbc.com'
}, {
name: "microsoft",
link: 'https://microsoft.com'
}];
});
</script>
<div ng-app="app" ng-controller="myCtrl">
<div class="bar">
<!--
1. If you want to search everything(both link and name), just use searchString
<input type="text" class="search" ng-model="searchString">
2. If you want to search only name change searchString to searchString.name
<input type="text" class="search" ng-model="searchString.name">
3. If you want to search only link change searchString to searchString.link
<input type="text" class="search" ng-model="searchString.link">
-->
<input type="text" class="search" ng-model="searchString" />
</div>
<ul class="data-ctrl">
<li ng-repeat="i in berkay | filter:searchString">
{{i.name}}
</li>
</ul>
</div>
i'm new on VueJS and i'm making a chat following a tutorial.
in the tutorial, the professor puts a v-model in a component. When I do this, the component is not "rendered" on the screen, and the console responds to "text is not defined," I can not find this problem anywhere, if someone can help me, I'll be grateful, follow my html and js.
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chat JS</title>
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<div class="container">
<div class="row">
<div id="app">
<router-link to="/chat">Vá para o Chat</router-link><br>
<router-link to="/rooms">Vá para as Salas</router-link><br><br><br>
<router-view></router-view>
</div>
</div>
</div>
<script src="https://www.gstatic.com/firebasejs/3.5.2/firebase.js"></script>
<script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript" src="node_modules/vue-router/dist/vue-router.min.js"></script>
<script type="text/javascript" src="node_modules/vuefire/dist/vuefire.min.js"></script>
<script type="text/javascript" src="app/app.js"></script>
</body>
</html>
JS
var firebaseApp = firebase.initializeApp(config);
var db = firebaseApp.database();
const chatComponent = {
template: `
<div class="panel panel-primary">
<div class="panel-heading">Chat</div>
<div class="panel-body" style="height: 400px; overflow-y: scroll;">
<ul class="chat list-unstyled">
<li class="clearfix"
v-bind:class="{left: !isUser(o.email), right: isUser(o.email)}" v-for="o in chat.messages">
<span v-bind:class="{'pull-left': !isUser(o.email), 'pull-right': isUser(o.email)}">
<img v-bind:src="o.photo" class="img-circle"/>
</span>
<div class="chat-body">
<strong>{{o.name}}</strong>
<p>
{{ o.text }}
</p>
</div>
</li>
</ul>
</div>
<div class="panel-footer">
<div class="input-group">
<input type="text" class="form-control input-md" placeholder="Digite sua Mensagem..."/>
<span class="input-group-btn">
<button class="btn btn-sucess btn-md">Enviar</button>
</span>
</div>
</div>
</div>
`,
data: function() {
return {
user: {
email: 'jose#gmail.com',
name: 'Jose Joao',
},
chat: {
messages: [
{
email: "fulano#gmail.com",
text: "Olá eu sou o Fulano",
name: "Fulano",
photo: "http://placehold.it/50/000FFF/fff&text=00"
},
{
email: "jose#gmail.com",
text: "Estou Joia, eu sou o Robo",
name: "Robo",
photo: "http://placehold.it/50/FFFFFF/fff&text=EU"
},
{
email: "jose#gmail.com",
text: "Tudo bem com voce",
name: "Robo",
photo: "http://placehold.it/50/FFFFFF/fff&text=EU"
}
]
}
};
},
methods:{
isUser:function(email){
return this.user.email == email;
}
}
};
const RoomsComponent = {
template:`
<div class="col-md-12" >
<div class="col-md-4" v-for="o in rooms">
<div class="panel panel-primary">
<div class="panel-heading">
{{ o.name }}
</div>
<div class="panel-body">
{{o.description}}<br>
Entrar
</div>
</div>
</div>
<div class="col-md-4">
<input type="text" id="problem"/>
<ul>
</ul>
</div>
</div>
`,
firebase:{
array: db.ref('array')
},
data: function() {
return {
rooms: [
{id: "001", name: "Duvidas", description: "Duvidas Gerais"},
{id: "002",name: "Cadastros/Login", description: "Duvidas sobre Acesso"},
{id: "003",name: "Planos", description: "Duvidas sobre os Planos"},
{id: "004",name: "Creditos", description: "Duvidas sobre os Creditos"},
{id: "005",name: "Modelos", description: "Duvidas sobre os Modelos"},
{id: "006",name: "Envios", description: "Duvidas sobre os Envios"}
]
};
},
methods:{
goToChat: function(room){
router.push('/chat/'+room.id)
},
insertData: function(){
this.$firebaseRefs.array.push({
text: this.text
});
}
}
};
const routes =[
{ path: '/chat/:room', component: chatComponent },
{ path: '/rooms', component: RoomsComponent }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
Recalling that the problem is in the input with id "problem" (to facilitate you) Basically as I said, just to put a V-model it of the error, if anyone knows, thank you!
You need to define your components as follows:
Vue.component('chat-component', {
template: `...`,
data: {
// your data
},
methods: {
// your methods
},
// and so on
});
You have only created javascript objects, not Vue components, in your sample code above.
You can also check the jsFiddle examples from previous questions on vue.js in stackoverflow, which will guide you on the syntax for creating Vue components, parent-child communication, etc.
I have just started to learn AngularJS.
I am trying to write this code with 3 files index.html and view1.html and view2.html . In index.html I have defined the module and controller function.In the controller 'sc' i have javascript object array with 2 fields name and city harcoded. I have used the router functionality to add a new view which will be used to search by the user and i have also added a button to dynamically insert a new pair of values into the object array.
But i am unable to print the name and city values in the view1 and view2. I am sure there is some problem with the scope but i am unable to find the error.
Below is the index.html file code.
<html ng-app="demo" >
<head>
<title>AngularStuff!!!</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body >
<!-- <div ng-controller='sc'>
</div>-->
<div ng-controller="sc">
<div ng-view=" "></div>
</div>
<script>
var demo=angular.module('demo',['ngRoute']);
demo.controller('sc',function($scope){
$scope.customers=[
{name:'Johnny',city:'ab'},
{name:'Jane',city:'ab'},
{name:'Apple',city:'tv'},
{name:'Clarice',city:'ku'},
{name:'Clayton',city:'lm'}
];
$scope.add=function()
{
$scope.customers.push({name:$scope.n.name,city:$scope.n.city}) ;
};
}
);
demo.config(
function($routeProvider)
{
$routeProvider
.when('/',
{
controller:'sc',
templateUrl:'View1.html'
}
)
.when('/View2',
{
controller:'sc',
templateUrl:'View2.html'
}
)
.otherwise({redirectTo:'/'});
}
);
</script>
</body>
</html>
Below is the view1.html File Code
<div >
<h2 align="center">View1</h2>
Name:
<input type="text" ng-model="filter.name"/>
<ul>
<li ng-repeat="cust in cutomers|filter:filter.name">
{{cust.name}}--{{cust.city}}
</li>
</ul>
Customer Name:
<input type="text" ng-model="n.name"/>
<br/>
Customer City:
<input type="text" ng-model="n.city"/>
<br/>
<button ng-click="add()">Add Customer</button>
View2
</div>
Below is the view2.html
<div >
<h2 align="center">View1</h2>
Name:
<input type="text" ng-model="filter.name"/>
<ul>
<li ng-repeat="cust in cutomers|filter:filter.name">
{{cust.name}}--{{cust.city}}
</li>
</ul>
Customer Name:
<input type="text" ng-model="n.name"/>
<br/>
Customer City:
<input type="text" ng-model="n.city"/>
<br/>
<button ng-click="add()">Add Customer</button>
View2
</div>
The views are loading properly but the values are not getting displayed.
<ul>
<li ng-repeat="cust in customers | filter:cust.name">
{{cust.name}} {{cust.city}}
</li>
</ul>
Here is a working plunker
I was working on developing a comment page based on https://thinkster.io/mean-stack-tutorial. But the page does not appear at all. Here is the code:
In index.ejs in views directory:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="/javascripts/ang.js"></script>
</head>
<body ng-app="peopleComments">
<script type="text/ng-template" id="/home.html">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="page-header">
<h2>Learn. Share. Popularize.</h2>
</div>
<p>Share here to let the world know.</p>
<hr/>
<div ng-repeat="comment in comments|orderBy:'-upvotes'" style="line-height:25px">
{{comment.username}} - {{comment.contents}}
<br>
{{comment.upvotes}}
<span class="glyphicon glyphicon-triangle-top" ng-click="increaseUpvotes(comment)" style="color:green"></span>
{{comment.downvotes}}
<span class="glyphicon glyphicon-triangle-bottom" ng-click="increaseDownvotes(comment)" style="color:red"></span>
<hr/>
</div>
<form ng-submit="addComment()">
<div class="col-xs-2">
<div class="form-group">
<input type="text" class="form-control" placeholder="Your Name" ng-model="username"></input>
</div>
</div>
<div class="col-xs-8">
<div class="form-group">
<input type="text" class="form-control" placeholder="What would you like to share?" ng-model="contents"></input>
</div>
</div>
<button class="btn btn-info" type="submit">Add My Entry</button>
</form>
</div>
</div>
</div>
</script>
</body>
</html>
In comments.js in models directory:
var mongoose = require('mongoose');
var CommentSchema = new mongoose.Schema({
username: String,
contents: String,
upvotes: {type: Number, default: 0},
downvotes:{type:Number, default:0}
});
CommentSchema.methods.upvote=function(cb){
this.upvotes+=1;
this.save(cb);
};
mongoose.model('Comment', CommentSchema);
In ang.js in public/javascripts directory:
var app=angular.module('peopleComments',['ui.router']);
app.factory('comments',['$http', function($http){
var c={
comments:[]
};
//loading all existing comments with getAll()
c.getAll=function(){
return $http.get('/comments').success(function(data){
angular.copy(data, c.comments);
});
};
//function which creates the new comments for updating in the database
c.create = function(comment) {
return $http.post('/comments', comment).success(function(data){
c.comments.push(data);
});
};
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
//setting up a home state
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'Base',
resolve: {
comment: ['comments', function(comments){ //using resolve property of ui-router - not rendering???
return comments.getAll();
}]
}
});
$urlRouterProvider.otherwise('home');
}]);
app.controller('Base',[
'$scope','comments',function($scope,comments){
$scope.addComment=function(){ //add new comments to the server/display existing ones
$scope.comments=comments.comments;
if(!$scope.username||$scope.username=='') {$scope.username='Anonymous';}
if(!$scope.contents||$scope.contents==''){return;}
comments.create({
username: $scope.username,
contents: $scope.contents,
}); $scope.comments.push({username:$scope.username,contents:$scope.contents,upvotes:0,downvotes:0});
$scope.username='';
$scope.contents='';
}
$scope.comments = [
{username: 'Diana', contents:'In either a quantum world or in a higher dimension, the past, present and future co-exist!', upvotes: 5, downvotes:0},
{username: 'Cindy', contents:'Never wash strawberries or any berry unless you intend to eat them right away or they will mold.', upvotes: 7, downvotes:0}
];
}]);
The comments given above should appear.. But they aren't.. Why??
I think your problem is that you've created a template, but you're not using the template.
I'm not 100% sure you need a template but try:
<div ng-include src="home.html"></div>
See this example of switching templates dynamically JSFiddle
It looks like the Controller will not wait for comment to load because it doesn't depend on it. Making the controller depend on the comment promise as well as the comments service should make the dependency clear to Angular.
app.controller('Base',[
'$scope','comments', 'comment', function($scope,comments,_comment){
// ...
}]);
The mistake was that I had to add
<ui-view></ui-view>
where I needed my template to load as per the ui-router syntax.