angularjs and calling function in the same object - angularjs

I use two simple form with angularjs
<form ng-controller="ctrs.ctr1">
<input type="text" placeholder="Name" ng-model="name" />{{getName()}}
</form>
and
<form ng-controller="ctrs.ctr2">
<input type="text" placeholder="Name" ng-model="name" />{{getName()}}
</form>
and s small script for e.g showing name twice
var ctrs = {
nameTwoTimes: function(name) {
return name+" "+name;
},
ctr1: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
return $scope.name+" "+$scope.name;
};
},
ctr2: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
this.nameTwoTimes($scope.name);
};
}
};
How to use the function nameTwoTimes, that in calling it is not "undefined"? Thanks.

Like this:
var nameTwoTimes: function(name) {
return name+" "+name;
};
var ctrs = {
ctr1: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
return $scope.name+" "+$scope.name;
};
},
ctr2: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
nameTwoTimes($scope.name);
};
}
};

Related

How to bind data in 'value' attribute of <input tag> to NET core MVC model using angular

I’ve been playing around with Upload file - Streaming method. The original code, here:
https://github.com/aspnet/Docs/tree/master/aspnetcore/mvc/models/file-uploads/sample/FileUploadSample
However, I’m trying to get the data in the value attribute of <input value=” ”> using Angular, the idea is that I can POST the value into my MVC model instead of whatever is typed by the user (as in the original code). So, I have done this change to the input value property.
Streaming/Index.cshtml:
<div ng-app="myApp">
<div ng-controller="myCtrl">
..
<input value="#Model.name” type="text" name="Name" ng-model="name"/>
..
<button ng-click="createUser()">Create User</button>
..
</div>
</div>
#section scripts{
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="~/js/app.js"></script>
}
However, with Angular code running under app.js, the following piece of code actually fails with status code 400. This is because the passed value is “” and not the data under of value attribute of the HTML input tag.
App.js:
var User = (function () {
function User(name) {
this.name = name;
}
return User;
}());
var myApp = angular.module('myApp', []);
myApp.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function () {
scope.$apply(function () {
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
myApp.service('userService', ['$http', function ($http) {
this.createUser = function(user) {
var fd = new FormData();
fd.append('name', user.name);
return $http.post('/streaming/upload', fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
});
};
}]);
myApp.controller('myCtrl', ['$scope', 'userService', function ($scope, userService) {
$scope.createUser = function () {
$scope.showUploadStatus = false;
$scope.showUploadedData = false;
var user = new User($scope.name);
userService.createUser(user).then(function (response) { // success
if (response.status == 200) {
$scope.uploadStatus = "User created sucessfully.";
$scope.uploadedData = response.data;
$scope.showUploadStatus = true;
$scope.showUploadedData = true;
$scope.errors = [];
}
},
function (response) { // failure
$scope.uploadStatus = "User creation failed with status code: " + response.status;
$scope.showUploadStatus = true;
$scope.showUploadedData = false;
$scope.errors = [];
$scope.errors = parseErrors(response);
});
};
}]);
function parseErrors(response) {
var errors = [];
for (var key in response.data) {
for (var i = 0; i < response.data[key].length; i++) {
errors.push(key + ': ' + response.data[key][i]);
}
}
return errors;
}
The solution must be a simple one, but after much research, I haven’t been able to find out how to modify it to make the data in the value=’’” attribute being passed across. This might be a stupid question but a headache for me however since I’m a total newbie regarding Angular. Please have some mercy, help.
Thanks
Use the ng-init directive to initialize the model:
<input ng-init="name= #Model.name" type="text" name="Name" ng-model="name"/>

Sharing scope data in controller

My spring mvc controller returns an object.
My scenario is:
On click of a button from one page say sample1.html load a new page say sample2.html in the form of a table.
In sample1.html with button1 and controller1--> after clicking button1-->I have the object(lets say I got it from backend) obtained in controller1.
But the same object should be used to display a table in sample2.html
How can we use this object which is in controller1 in sample2.html?
You can use a service to store the data, and inject it in your controllers. Then, when the value is updated, you can use a broadcast event to share it.
Here is a few example:
HTML view
<div ng-controller="ControllerOne">
CtrlOne <input ng-model="message">
<button ng-click="handleClick(message);">LOG</button>
</div>
<div ng-controller="ControllerTwo">
CtrlTwo <input ng-model="message">
</div>
Controllers
function ControllerOne($scope, sharedService) {
$scope.handleClick = function(msg) {
sharedService.prepForBroadcast(msg);
};
}
function ControllerTwo($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = sharedService.message;
});
}
Service
myModule.factory('mySharedService', function($rootScope) {
var sharedService = {};
sharedService.message = '';
sharedService.prepForBroadcast = function(msg) {
this.message = msg;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('handleBroadcast');
};
return sharedService;
});
JSFiddle demo
you can use factory to share data between controllers
<div ng-controller="CtrlOne">
<button ng-click="submit()">submit</button>
</div>
<div ng-controller="CtrlTwo">
{{obj}}
</div>
.controller('CtrlOne', function($scope, sampleFactory) {
$scope.sampleObj = {
'name': 'riz'
}; //object u get from the backend
$scope.submit = function() {
sampleFactory.setObj($scope.sampleObj);
}
})
.controller('CtrlTwo', function($scope, sampleFactory) {
$scope.obj = sampleFactory.getObj();
})
.factory('sampleFactory', function() {
var obj = {};
return {
setObj: function(_obj) {
obj = _obj;
},
getObj: function() {
return obj;
}
}
})

$scope is not defined in a directive controller

I have a very basic demo app. The HTML:
<div ng-app="MyApp" ng-controller="Shapes">
<shapes></shapes>
</div>
and my js file:
app.directive('shape',
function () {
var directive = {};
directive.restrict = 'E';
directive.template = '<span>Shape Name: {{shape.Name}}, Shape Area: {{shape.Area}}</span>';
directive.scope = {
shape: "=name"
};
return directive;
});
app.directive('shapes',
function () {
var controller = [
'$scope', '$http', function ($scope, $http) {
$scope.height = 0, $scope.width = 0;
$http.get('/api/Values').then(function (respnse) {
$scope.shapes = respnse.data;
});
$scope.addShape = function () {
$http.post('api/Values', { Width: 1, Height: 1 }).then(function (res) { });
};
}
];
var directive = {};
directive.restrict = 'E';
directive.template = '<div ng-repeat="shape in shapes"><shape name="shape"></shape></div>' +
'<div>Height:<input type="text" ng-model="height"></input>, Width:<input type="text" ng-model="width"></input>' +
'<button ng-click="addShape()">Add Shape</button></div>';
directive.controller = controller;
return directive;
});
My problem - in the $scope.addShape function, $scope is not defined. Why? $http is defined and working well.

Simple $scope test not working

I'm trying to do a simple $scope controller practice. The app should show the result expression if the text value is the correct one...
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text"/>
<p>{{text}} {{result}}</p>
</scope-test>
And this is the app...
angular.module('angular-tests', [])
.directive('scope-test', function(){
return{
restrict:'E',
controller: function($scope){
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
}
};
});
Ng-model is the only thing working fine.
Thanks!
Each controller function called once per load (like a constructor). It means that you check your value only once at the start.
You need to create a function inside your controller, which will be ran by each change:
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text" ng-change="changeHandler" />
<p>{{text}} {{result}}</p>
</scope-test>
angular.module('angular-tests', [])
.directive('scope-test', function(){
return{
restrict:'E',
controller: function($scope){
$scope.changeHandler = function(){
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
}
}
};
});
The most simple solution would be to include a watch in your directive.
Angular Code
var myApp = angular.module('myApp',[])
.directive('scopeTest', function(){
return{
restrict:'E',
controller: function($scope) {
$scope.$watch('text', function() {
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
})
}
};
});
HTML Code
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text"/>
<p>{{text}} {{result}}</p>
</scope-test>
Hope it helps!
Here is the fiddle: http://jsfiddle.net/au2uL08u/
Also note that your directive name needs to be camelCase. Then when you place your directive inside the template, you use hyphens for each word that begins with a capital.
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text" ng-change="evaluateText()"/>
<p>{{text}} {{result}}</p>
</scope-test>
angular.module('angular-tests', [])
.directive('scopeTest', function(){
return{
restrict:'E',
controller: function($scope){
$scope.evaluateText = function () {
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
};
$scope.evaluateText();
}
};
});

Accessing a service or controller in my link function - Angular.js

I have a directive, but I am having a problem access the controller and my service that is injected into it. Here is my directive:
angular.module('clinicalApp').directive('chatContainer', ['encounterService', function(encounterService) {
return {
scope: {
encounter: '=',
count: '='
},
templateUrl: 'views/chat.container.html',
controller: 'EncounterCtrl',
link: function(scope, elem, attrs, controller) {
scope.addMessage = function(message) {
//RIGHT HERE
scope.resetChat();
};
scope.resetChat = function() {
scope.chatText = '';
scope.updateCount(scope.chatText);
};
}
};
}]);
You can see that I am attaching a couple of functions to my scope inside the link function. Inside those methods, like addMessage, I don't have access to my controller or the service that is injected into the directive. How do I acceess the controller or service?
UPDATE
Here is the service:
angular.module('clinicalApp').factory('encounterService', function ($resource, $rootScope) {
var EncounterService = $resource('http://localhost:port/v2/encounters/:encounterId', {encounterId:'#id', port: ':8280'}, {
search: {
method: 'GET'
}
});
var newEncounters = [];
var filterTerms = {};
EncounterService.pushNewEncounter = function(encounter) {
newEncounters.push(encounter);
$rootScope.$broadcast('newEncountersUpdated');
};
EncounterService.getNewEncounters = function() {
return newEncounters;
}
EncounterService.clearNewEncounters = function() {
newEncounters = [];
}
EncounterService.setFilterTerms = function(filterTermsObj) {
filterTerms = filterTermsObj;
$rootScope.$broadcast('filterTermsUpdated');
EncounterService.getFilterTerms(); //filter terms coming in here, must redo the search with them
}
EncounterService.getFilterTerms = function() {
return filterTerms;
}
return EncounterService;
});
and the chat.container.html
<div class="span4 chat-container">
<h5 class="chat-header">
<span class="patient-name-container">{{encounter.patient.firstName }} {{encounter.patient.lastName}}</span>
</h5>
<div class="chat-body">
<div class="message-post-container">
<form accept-charset="UTF-8" action="#" method="POST">
<div class="text-area-container">
<textarea id="chatBox" ng-model="chatText" ng-keyup="updateCount(chatText)" class="chat-box" rows="2"></textarea>
</div>
<div class="counter-container pull-right">
<span class="muted" id="counter">{{count}}</span>
</div>
<div class="button-container btn-group btn-group-chat">
<input id="comment" class="btn btn-primary btn-small btn-comment disabled" value="Comment" ng-click="addMessage(chatText)"/>
</div>
</form>
<div messages-container messages="encounter.comments">
</div>
</div>
</div>
</div>
Here is Demo Plunker I played with.
I removed scope{....} from directive and added 2 values in controller and directive to see how they change regards to action.
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
// listen on any change of chatText in directive
$scope.$watch(function () {return $scope.chatText;},
function (newValue, oldValue) {
if (newValue == oldValue) {return;}
$scope.chatTextFromController = newValue;
}, true);
});
app.directive('chatContainer', ['encounterService', function(encounterService) {
return {
templateUrl: 'chat.container.html',
link: function(scope, elem, attrs) {
scope.countStart = scope.count;
scope.updateCount = function(chatText) {
alert('updateCount');
scope.count = scope.countStart - chatText.length;
};
scope.addMessage = function(message) {
alert('addMessage');
encounterService.sayhello(message);
scope.resetChat();
};
scope.resetChat = function() {
alert('resetChat');
scope.chatText = 'someone reset me';
scope.name = "Hello " + scope.name;
scope.updateCount(scope.chatText);
};
}
};
}]);
app.service('encounterService', function() {
var EncounterService = {};
EncounterService.sayhello = function(message) {
alert("from Service " + message);
};
return EncounterService;
});
HTML
<body ng-controller="MainCtrl">
<div chat-container></div>
<pre>chatText from directive: {{chatText|json}}</pre>
<pre>chatText from controller: {{chatTextFromController|json}}</pre>
<pre>name: {{name|json}}</pre>
</body>

Resources