Hi all my requirement is to share input field data using get set method in factory with another controller.
angular.module('dataModule',[]).factory('myFact',function($http){
var user = {};
return {
getDetails: function () {
return user ;
},
setDetails : function (name,add,number) {
user.name = name;
user.add = add;
user.number = number;
}
}
});
Here is controller code.
angular.module('dataModule',[]).controller('thirdCtrl',function(myFact,$scope) {
$scope.saw=function(){
alert("hello get set method");
$scope.user=myFact.user.getDetails();
console.log(user);
};
});
Here is my html code
<div ng-controller="thirdCtrl">
<h1>hello gaurav come here after click one.</h1>
<div>
<lable>NAME</lable>
<div><input type="text"ng-model="user.name"></div>
</div>
<div>
<lable>ADDRESS</lable>
<div><input type="text"ng-model="user.add"></div>
</div>
<div>
<lable>MOBILE</lable>
<div><input type="number"ng-model="user.number"></div>
</div>
</br>
</br>
<button type="button" ng-click="saw()">Click</button>
</div>
Here is my app.js
var app = angular.module('sapient',['ui.router','dataModule']);
app.config(['$stateProvider','$urlRouterProvider',function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('one', {
url: '/one',
templateUrl: 'view/sap.html',
controller: 'sapCtrl'
})
.state('two', {
url: '/two',
templateUrl: 'view/two.html',
controller: 'secondCtrl'
})
.state('three', {
url: '/three',
templateUrl: 'view/three.html',
controller: 'thirdCtrl'
});
$urlRouterProvider.otherwise('two');
}])
Any Suggestions
Thanks in advance
The problem is you're recreating the module. Remove the [] (array of module dependencies) to make angular retrieve the previously created module, rather than create a new one.
Change:
angular.module('dataModule',[]).controller('thirdCtrl',function(myFact,$scope)
To:
angular.module('dataModule').controller('thirdCtrl',function(myFact,$scope)
Related
I'm trying to create a component for create "Tweets" in my own website, and when I try to write something into textarea (can't write anything)
I have this image which shows the error:
And that's my code in "editorTweets.component.js":
class EditorTweetsComponentCtrl {
constructor($scope, $state, User, Tweets){
"ngInject";
this._Tweets = Tweets;
this._$state = $state;
this._$scope = $scope;
this.currentUser = User.current;
console.log(this.currentUser);
this.tweet = {
body: ''
}
}
submit() {
console.log(this.tweet.body);
}
}
let EditorTweets = {
bindings: {
tweet: '='
},
controller: EditorTweetsComponentCtrl,
templateUrl: 'components/tweets-helpers/editorTweets.html'
};
export default EditorTweets;
and the .html view:
<div class="container-editor-tweets">
<div class="left-editor-tweets">
<img ng-src="{{$ctrl.currentUser.image}}" alt="Img-User"/>
</div>
<div class="right-editor-tweets">
<div class="editor-tweet-body">
<textarea name="tweet_msg" id="tweet_msg" placeholder="Whats going on?..." ng-model="$ctrl.tweet.body"></textarea>
</div>
<div class="editor-tweet-options">
<button class="btn-submit-tweet" type="button" ng-click="$ctrl.submit()">Tweet</button>
</div>
</div>
</div>
The component shouldn't have bindings, because I don't need to send any data, so the component is trying to get "tweet" and that's the error.
This is the correct code:
let EditorTweets = {
controller: EditorTweetsComponentCtrl,
templateUrl: 'components/tweets-helpers/editorTweets.html'
};
I'm fairly new to Angular, and I'm trying to figure out why scope variables isn't updating after they've been set.
I'm calling a Node API returing json objects containing my data. Everything seems to work fine except setting $scope.profile to the data returned from the API.
Setup:
app.js
(function() {
var app = angular.module("gamedin", []);
app.controller('profileController', function($scope, $http, $timeout) {
$scope.profile = {};
$scope.getProfile = function() {
var vanityUrl = $scope.text.substr($scope.text.lastIndexOf('/') + 1);
$http.get('/steamid/' + vanityUrl)
.then(function(data) {
$http.get('/profile/' + data.data.response.steamid)
.then(function(data) {
console.log(data.data.response.players[0]); // Correct data
$scope.profile = data.data.response.players[0]; // View isn't updated
})
})
// Reset the input text
$scope.text = "";
}
});
...
app.directive('giHeader', function() {
return {
restrict: 'E',
templateUrl: 'components/header/template.html'
};
})
app.directive('giProfile', function() {
return {
restrict: 'E',
templateUrl: 'components/profile/template.html'
}
})
})();
components/header/template.html
<header>
<div class="header-content" ng-controller="profileController">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="header-content-inner">
<input ng-model="text" ng-keyup="$event.keyCode == 13 && getProfile()" class="form-control" type="text" placeholder="Enter Steam URL">
</div>
<p>e.g., http://steamcommunity.com/id/verydankprofilelink</p>
</div>
<div class="col-md-3"></div>
</div>
</header>
components/profile/template.html
<div class="container">
<div ng-controller="profileController">
<h3>
<strong>Username: {{ profile.personaname }}</strong>
</h3>
<p> SteamID: {{ profile.steamid }}</p>
</div>
</div>
index.html
<!doctype html>
<html ng-app="gamedin">
<head>
...
</head>
<body>
...
<gi-header></gi-header>
<gi-profile></gi-profile>
...
</body>
</html>
I've tried wrapping it in $scope.$apply, like this
$scope.$apply(function () {
$scope.profile = data.data.response.players[0];
});
... which resulted in Error: [$rootScope:inprog]
Then I tried
$timeout(function () {
$scope.profile = data.data.response.players[0];
}, 0);
and
$scope.$evalAsync(function() {
$scope.profile = data.data.response.players[0];
});
... and although no errors were thrown, the view still wasn't updated.
I realize that I'm probably not understanding some aspects of angular correctly, so please enlighten me!
The problem is that you have 2 instances of profileController, one in each directive template. They should both share the same instance, because what happens now is that one instance updates profile variable on its scope, and the other is not aware. I.e., the profileController instance of header template is executing the call, and you expect to see the change on the profile template.
You need a restructure. I suggest use the controller in the page that uses the directive, and share the profile object in both directives:
<gi-header profile="profile"></gi-header>
<gi-profile profile="profile"></gi-profile>
And in each directive:
return {
restrict: 'E',
scope: {
profile: '='
},
templateUrl: 'components/header/template.html'
};
And on a more general note - if you want to use a controller in a directive, you should probably use the directive's "controller" property.
Try using this method instead:
$http.get('/steamid/' + vanityUrl)
.then(function(data) {
return $http.get('/profile/' + data.data.response.steamid).then(function(data) {
return data;
});
})
.then(function(data) {
$scope.profile = data.data.response.players[0]; // View isn't updated
})
Where you use two resolves instead of one and then update the scope from the second resolve.
I'm using the excellent AngularJS Rails Resources and with one object - which has deep nested objects in turn - when I update some of its properties, the updated property does not show on the template until I reload the page.
Let start from the beginning: here's my object:
var invoice = Invoice.get($stateParams.invoiceId).then(function (result) {
$scope.invoice = result;
});
And here's how I open my modal to edit the values:
$scope.openEdit = function (edit) {
$scope.editModal = $modal.open({
templateUrl: 'editModalContent.html',
controller: 'InvoiceShowController',
size: 'lg'
});
$scope.editModal.result.then(function(select) {
});
};
$scope.cancel = function () {
$scope.$close();
};
$scope.ok = function () {
$scope.invoice.update().then(function (result) {
$scope.cancel();
console.log(result);
});
};
In my view I have the following:
...
<li>{{invoice.trading_details.trading_name}}</li>
<li>{{invoice.trading_details.trading_address_1}}</li>
...
In the modal body I have the following:
...
<div class="form-group">
<label for="exampleInputEmail1">Trading Name</label>
<input ng-model="invoice.trading_details.trading_name" type="text" class="form-control" id="exampleInputEmail1">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Trading Address Line 2</label>
<input ng-model="invoice.trading_details.trading_address_1" type="text" class="form-control" id="exampleInputEmail1">
</div>
...
So when I edit the properties in the modal and console the object, the changes are there. When I save and get the result back, the changes are there, but for whatever reason the view is not updating.
Any ideas?
EDIT: My whole controller
It looks like you are missing the resolve setting. It passing data to your modal.
$scope.openEdit = function (edit) {
$scope.editModal = $modal.open({
templateUrl: 'editModalContent.html',
controller: 'InvoiceShowController',
size: 'lg',
//notice a function is returning the data
resolve: {
invoice: function(){
return $scope.invoice;
}
}
});
};
EDIT
Link to Plunker: http://plnkr.co/edit/IJvdBJrJngsNYaG39Gfh?p=preview
Notice how the resolve creates an instance invoice that is passed into the editCtrl.
UPDATE
You can also do
$scope.editModal = $modal.open({
templateUrl: 'editModalContent.html',
controller: 'InvoiceShowController',
size: 'lg',
//notice a function is returning the data
resolve: {
invoice: function(){
return Invoice.get($stateParams.invoiceId);
}
}
});
...because the resolve can process a promise.
I am using UI-Router for an Angular app. I can't seem to find what I am doing wrong. I am also not getting any errors which is making it really difficult for me to debug. Followed the docs as well and I am following their steps. My controller function is working when I don't nest it in a child view. Can someone please direct me to what I am doing wrong? Thanks in advance!
APP.JS
'use strict';
var app = angular.module('americasTopStatesApp', ['ui.router', 'ngAutocomplete']);
app.run(function($state, $rootScope) {
$rootScope.$state = $state;
});
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.otherwise('/home');
$stateProvider
//HOME
.state('home', {
url: '/home',
templateUrl: './app/views/homeTmpl.html',
controller: 'homeCtrl'
})
//RANKINGS
.state("rankings", {
url: "/rankings",
templateUrl: './app/views/rankingsTmpl.html',
controller: 'rankingsCtrl'
})
// RANKINGS CHILDREN
.state('rankings.data', {
url: '/data',
templateUrl: './app/views/rankingsDataTmpl.html',
controller: 'rankingsCtrl',
parent: 'rankings'
})
});
CONTROLLER rankingsCtrl
'use strict';
app.controller('rankingsCtrl', function($scope, rankingsService) { //Start Controller
// ***********************************************
// *************** GET LATEST DATA ***************
// ***********************************************
$scope.getAllStateRankings = function() {
rankingsService.getStateRankingsData().then(function(data) {
$scope.showRankings = true;
// console.log("Contoller Data", data);
$scope.states = data;
});
};
$scope.showRankings = false;
$scope.getAllStateRankings();
}); //End Controller
PARENT VIEW rankingsTmpl.html
<div class="rankings-heading">
<h1>America's Top States</h1>
<button ng-click="getAllStateRankings()">
<a ui-sref="rankings.data" id="data" class="btn">Data</a>
</button>
</div>
</div ui-view></div>
Child View (Nested ui-view) rankingsDataTmpl.html
<div class="rankings-container" ng-show="showRankings">
<div class="panel panel-primary" ng-repeat='state in states'>
<div class="panel-heading">
<h3 class="panel-title">{{state.state}}</h3>
</div>
<div class="panel-body">
Economy: {{state.economy}}<br>
Capital Access: {{state.accessToCapital}}<br>
Business: {{state.business}}<br>
Cost of living: {{state.costOfLiving}}<br>
</div>
</div>
</div>
Screen Shot
There is a working plunker
In this case, when we have parent child and angular's UI-Router, we should not use solution based on
parent and child has same controller. // WRONG approach
Because they in fact do have JUST same type. The instance of that type 'rankingsCtrl' in runtime is different.
What we need is:
How do I share $scope data between states in angularjs ui-router?
scope inheritance, driven by reference object, e.g. $scope.Model = {}
There is adjusted controller:
.controller('rankingsCtrl', ['$scope', function($scope) {
$scope.Model = {};
$scope.getAllStateRankings = function() {
//rankingsService.getStateRankingsData().then(function(data) {
$scope.Model.showRankings = true;
// console.log("Contoller Data", data);
$scope.Model.states = data;
//});
};
$scope.Model.showRankings = false;
$scope.getAllStateRankings();
}])
At the end, child can have different controller with its own logic for the child view:
.state("rankings", {
url: "/rankings",
templateUrl: 'app/views/rankingsTmpl.html',
controller: 'rankingsCtrl'
})
// RANKINGS CHILDREN
.state('rankings.data', {
url: '/data',
templateUrl: 'app/views/rankingsDataTmpl.html',
controller: 'rankingsChildCtrl',
parent: 'rankings'
})
Also, the parent view should have fixed div:
// wrong
</div ui-view></div>
// starting tag
<div ui-view></div>
Check it here in action
I am currently following this tuto on MEAN.js : https://thinkster.io/mean-stack-tutorial/ .
I am stuck into the end of "Wiring Everything Up", I am completlty new to angular so I am not pretending I understood everything I did. Here is the situation :
We are using the plugin ui-router.
First here is the html template :
<form name="addComment" ng-submit="addComment.$valid && addComment()"novalidate>
<div class="form-group">
<input class="form-control" type="text" placeholder="Comment" ng-model="body" required/>
</div>
<button type="submit" class="btn btn-primary">Comment</button>
</form>
The error "Error: args is null $parseFunctionCall" occurs only when I submit the form
Then, here is the configuration step for this page :
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('posts', {
url : '/posts/{id}',
templateUrl: '/posts.html',
controller : 'PostsCtrl',
resolve : {
post: ['$stateParams', 'posts', function ($stateParams, posts) {
return posts.get($stateParams.id);
}]
}
});
$urlRouterProvider.otherwise('home');
}]);
There, is the controller :
app.controller('PostsCtrl', ['$scope', 'posts', 'post',
function ($scope, posts, post) {
$scope.post = post;
$scope.addComment = function () {
posts.addComment(post._id, {
body : $scope.body,
author: 'user'
}).success(function (comment) {
$scope.post.comments.push(comment);
});
$scope.body = '';
};
$scope.incrementUpVote = function (comment) {
posts.upvoteComment(post, comment);
};
}]);
And Finally, the factory where the posts are retrieved from a remote webservice
app.factory('posts', ['$http', function ($http) {
var o = {
posts: []
};
o.get = function (id) {
return $http.get('/posts/' + id).then(function (res) {
return res.data;
});
};
o.addComment = function (id, comment) {
return $http.post('/posts/' + id + '/comments', comment);
};
return o;
}]);
I've only given the parts that I think are relevant.
I suspect that the problem is comming from the promise and the scope which have been unlinked. I searched about promises but I think that ui-router is doing it differently.
I tried some $watch in the controller but without succeding.
Has anyone some idea about that ? Thank you in advance
The form name addComment (used for addComment.$valid) and the function addComment added to the scope are clashing with each other, rename one or the other.
See the Angular docs for the form directive:
If the name attribute is specified, the form controller is published
onto the current scope under this name.
As you are manually also adding a function named addComment, it is using the wrong one when evaluating the ng-submit.