AngularJS: Pass textbox value to services - html

I am new in angularJS. Currently working on services. I tried to pass text-box value to services. I don't know how to pass. I code but it's not working.
app.service("wishService", function ($timeout) {
this.wishHim = function (_wishMessage) {
$timeout(function () {
alert('Hi ,' + _wishMessage);
}, 2000);
}
});
app.controller('wishCtrl', ['$scope', function ($scope, wishService) {
$scope.Message = "";
$scope.SendMessage = function (wishMessage) {
wishService.wishHim(wishMessage);
};
}]);
<div ng-controller="wishCtrl">
Wish Message: <input type="text" ng-model="wishMessage" />
<input type="button" value="Send Message" ng-click="SendMessage(wishMessage)" /><br />
Your Message : {{Message}}
</div>
DEMO

wishService injection problem
app.controller('wishCtrl', ['$scope', 'wishService', function ($scope, wishService) {
$scope.Message = "";
$scope.SendMessage = function (wishMessage) {
wishService.wishHim(wishMessage);
};
}]);

I fixed your code, see the PLUNK here. While what Sandeep said is correct, you also had a TON of other problems. Refer to what I changed.
Edit: It was brought to my attention that what I changed your code to is the format of a factory, rather than a service:
app.service("MessageService", function () {
var service = {
msg: undefined,
setMsg: function(msg){
this.msg = msg;
},
getMsg: function(msg){
return this.msg;
}
}
return service;
});

Related

Call angular function inside ng-repeat and return array

I searched for this but I did not get any answer as I want, please give me a solution, I want to use ng-init inside ng-repeat, ng-init should give me different response at every loop here is my HTML
<html>
<body ng-app="crmApp">
<div ng-controller="customerDetailController">
<div ng-repeat="clientDetail in client">
<p>{{clientDetail.name}}</p>
<div ng-init="seoDetails = getCustDetail(clientDetail.name)">
<p>{{seoDetails.cust_Name}}</p>
</div>
</div>
</div>
</body>
</html>
and my js is
<script>
var crmMain = angular.module('crmApp', ['ngRoute','ngMaterial']);
crmMain.controller('customerDetailController',function customerDetailController($scope, $http, customerDetailFactory,$window) {
$scope.client = [];
$scope.init = function () {
$scope.getCustomerData();
};
$scope.getCustomerData = function () {
customerDetailFactory.getCustomerDetailData().then(function
(response) {
$scope.client = response.data;
});
};
$scope.getCustDetail = function (Name) {
var custDetail = [];
custDetail = customerDetailFactory.getCustomerDetailData(Name).then(function (response) {
alert(response.data.cust_Name);
return response.data;
});
return custDetail;
};
$scope.init();
});
crmMain.factory('customerDetailFactory', ['$http', function ($http) {
var factory = {};
var url = 'phpFile/customerDetail.php';
factory.getCustomerDetailData = function (Name) {
return $http({
method: 'POST',
url: url,
data: {
'functionName': 'clientDetailPage',
'customerName': Name
}
});
};
return factory;
}]);
</script>
In inside getCustDetail function I was given alert in there it 'll show name, but I don't know why it not showing in HTML.is anything wrong I did?
I have got one solution for this, I think I have to use Promises for this, but I don't know how to use it can anyone help me in this?
You cannot use ng-init for this purpose.
You've to do the data fetching inside the controller itself. That is like,
customerDetailFactory.getCustomerDetailData()
.then(function(response) {
$scope.client = response.data;
// for each clients, fetch 'seoDetails'
$scope.client.forEach(function(client) {
customerDetailFactory.getCustomerDetailData(client.name)
.then(function (response) {
// I hope response.data contains 'cust_Name'
client.seoDetails = response.data;
})
});
});
Now, in the view, you can directly use the seoDetails property
<div ng-repeat="clientDetail in client">
<p>{{clientDetail.name}}</p>
<p>{{clientDetail.seoDetails.cust_Name}}</p>
</div>

AngularJs #how to pass scope variable in on change event in directive in input file

I am not able to pass data to controller's function through angular directive, directive has one change event. In which i want to pass my dynamic id.
In controller i have myArray
$scope.myArray = [1,2,3,4,5];
I have following html.
<div ng-repeat="data in myArray track by $index">
<input type="file" ng-upload-change="uploadFile($event, $id)" my-id="$index">
<div>
In Controller:
$scope.uploadFile = function($event, $id){
var files = $event.target.files;
console.log("id:"+$id);
};
In directive:
app.directive('ngUploadChange', function() {
return{
scope:{
ngUploadChange:"&",
myId:"="
},
link:function($scope, $element, $attrs){
$element.on("change",function(event){
$scope.ngUploadChange({$event: event, $id : $scope.myId});
})
$scope.$on("$destroy",function(){
$element.off();
});
}
}
});
As you can see that when i pass uploadFile function to ngUploadChange directive, it always pass first id (in this case it is 1) to controllers function.
I am not getting updated id every time.
Thanks in advance.
When you want to pass parameters through the function, you can use "=" instead of "&" for that attr binding, and in your HTML, you can specify like this:
<input type="file" ng-upload-change="uploadFile" ... />
And, I changed the way you were passing an object of params since there is no need to create that object.
Now, if you see the code snippet below, it correctly logs id: x (0-based) on each file upload.
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
myApp.controller('MyCtrl', function MyCtrl($scope) {
$scope.myArray = [1, 2, 3, 4, 5];
$scope.uploadFile = function($event, $id) {
var files = $event.target.files;
console.log("id: " + $id);
};
});
myApp.directive('ngUploadChange', function() {
return {
scope: {
ngUploadChange: "=",
myId: "="
},
link: function($scope, $element, $attrs) {
$element.on("change", function(event) {
$scope.ngUploadChange(event, $scope.myId);
})
$scope.$on("$destroy", function() {
$element.off();
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="data in myArray">
<input type="file" ng-upload-change="uploadFile" my-id="$index">
</div>
</div>
It is better to write the directive without isolate scope.
app.directive('ngUploadChange', function() {
return{
/*
scope:{
ngUploadChange:"&",
myId:"="
},*/
link:function($scope, $element, $attrs){
$element.on("change",function(event){
var locals = { $event: event,
$id : $scope.$eval($attrs.myId)
};
$scope.$eval($attrs.ngUploadChange, locals);
});
/*
$scope.$on("$destroy",function(){
$element.off();
});*/
}
}
});
Use $scope.$eval instead of isolate scope bindings.
Isolate scope adds a scope and additional watchers which have been known to cause digest cycle delays that fight the ngModelController.

Redirect the JSON response to another html page (Angular)

I just recently started using Angular, and I am trying to redirect the response of http.get to another html page which is result.html. I used services to share data:
Here is my controller code:
app.controller("controller", function($scope, $http, $window, sharedProperties){
$scope.generate = function(){
$http.get('repositories', {params: { username : $scope.username }}).
then(function mySucces(response) {
$scope.error = "";
sharedProperties.setData(response.data);
$window.location.href = '/result.html';
}, function myError() {
$scope.error = "Wrong Username";
});
}
});
app.controller("resultController", function($scope, $window,sharedProperties){
$scope.names = sharedProperties.getData();
$scope.home = function() {
$window.location.href = '/index.html';
}
});
Here is the services.js code:
app.service('sharedProperties', function() {
var data;
return {
getData: function() {
return data;
},
setData: function(value) {
data = value;
},
}
});
Here is the index.html body:
<div ng-app="App" ng-controller="controller">
<p>
<input type="text" ng-model="username" placeholder="Enter username here" required>
<button ng-click="generate()">Generate</button>
</p>
{{ error }}
</div>
And here is the result.html that I want the response goes to:
<div ng-app="App" ng-controller="resultController">
<p><button ng-click="home()">Home</button></p>
<ul>
<li ng-repeat="x in names">
{{ "Name: " + x.name + ", Languages: " + x.languages }}
</li>
</ul>
</div>
The controller set the response data through sharedProperties so the resultController can use it, however after the page redirects to result.html the result is not shown.
UPDATE
It seems the data is not shared between the two controller, console.log shows undefined. Is it because of 2 different html files? or is it because of redirect?
UPDATE 2
I realized that redirect will reset all the data, so I use sessionStorate for the service:
app.service('sharedProperties', function() {
return {
getData: function() {
return sessionStorage.sharedProperties;
},
setData: function(value) {
sessionStorage.sharedProperties = value;
},
}
});
however console.log instead of showing the values of json, it shows:
"[object Object],[object Object],[object Object],[object Object],[object Object]"
The real value is suppose to be:
[{"name":"git-consortium","languages":"No Language Reported"},{"name":"hello-worId","languages":"No Language Reported"},{"name":"Hello-World","languages":"No Language Reported"},{"name":"octocat.github.io","languages":"CSS JavaScript HTML "},{"name":"Spoon-Knife","languages":"CSS HTML "}]
Any thoughts on this?
Even Though the response that I was getting was json, I had to still convert to json using angular.toJson().
Here is the service to save the json data:
app.service('sharedProperties', function() {
return {
getData: function() {
return angular.fromJson(sessionStorage.sharedProperties);
},
setData: function(value) {
sessionStorage.sharedProperties = angular.toJson(value);
},
}
});
So now even after redirecting to another page, I can still access the data.

how to authenticate myself asynchronously on the Google Drive API using AngularJS and HTML

Could someone determine how to authenticate myself asynchronously on the Google Drive API using AngularJS and HTML?
I am getting stuck on the call to gapi.auth.authorize because the callback function never gets called:
Here is the AngularJS--HTML5 code excerpt which does not work currently,
var app = angular.module('myApp', []);
app.service('googleService', ['$http', '$rootScope', '$q', function ($http, $rootScope, $q) {
this.login = function () {
gapi.auth.authorize(
{ client_id: '1009536034660-armd84ckoemm3jan35ceupjhdsmo0fa1.apps.googleusercontent.com', scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email' , immediate: true },
this.handleAuthResult);
return deferred.promise;
}
this.handleClientLoad = function {
gapi.client.setApiKey(apiKey);
gapi.auth.init(function () { });
window.setTimeout(checkAuth, 1);
};
this.checkAuth = function () {
gapi.auth.authorize({
client_id: clientId,
scope: scopes,
immediate: true,
hd: domain
}, this.handleAuthResult);
};
this.handleAuthResult = function (authResult) {
if (authResult && !authResult.error) {
var data = {};
gapi.client.load('oauth2', 'v2', function () {
var request = gapi.client.oauth2.userinfo.get();
request.execute(function (resp) {
data.email = resp.email;
deferred.resolve(data);
});
});
} else {
deferred.reject('error');
}
};
this.handleAuthClick = function (event) {
gapi.auth.authorize({
client_id: clientId,
scope: scopes,
immediate: false,
hd: domain
}, this.handleAuthResult);
return false;
};
}]);
app.controller('myController', ['$scope', 'googleService', function ($scope, googleService) {
$scope.login = function () {
$scope.login = function () {
googleService.login().then(function (greeting) {
console.log('Success: ' + greeting);
}, function (reason) {
console.log('Failed: ' + reason);
}, function (update) {
console.log('Got notification: ' + update);
});
};
};
}]);
} else {
deferred.reject('error');
}
};
});
Why is the gapi.auth.authorize failing to call the callback?
First I checked this hypothesis stackoverflow.com/questions/20036893/… and it was incorrect. Next I checked this hypothesis : stackoverflow.com/questions/31659414/… and it was also wrong.
I even tried using Brendan's SetTimeout workaround in this URL, https://groups.google.com/forum/#!topic/google-api-javascript-client/GuFxPzqQ9-0 and it did not function properly.
In addition, I requested and obtained a new OAuth2 client id with the correct javascript origin. Evidently , the onload callback is only called after successful loading of the script. Or, is there a timeout possibility for the callback to be invoked?
Here is Windows 7 ASP.NET program written entirely in Javascript and HTML which works properly :
<html>
<head>
<title>Google+ Sign-in button demo: rendering with JavaScript</title>
<style type="text/css">
html, body { margin: 0; padding:0;}
#signin-button {
padding: 5px;
}
#oauth2-results pre { margin: 0; padding:0; width: 600px;}
.hide { display: none;}
.show { display: block;}
</style>
<script src="https://apis.google.com/js/client:platform.js" type="text/javascript"></script>
<script type="text/javascript">
var loginFinished = function (authResult) {
if (authResult) {
console.log(authResult);
}
gapi.client.load('oauth2', 'v2', function () {
gapi.client.oauth2.userinfo.get()
.execute(function (resp) {
// Shows user email
console.log(resp.email);
});
});
};
var options = {
'callback': loginFinished,
'approvalprompt': 'force',
'clientid': '375218714272ao7690jhv6sk7jphi0jf3l5t500sajvt.apps.googleusercontent.com',
'scopes': ['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/drive.readonly'],
'requestvisibleactions': 'http://schemas.google.com/CommentActivity http://schemas.google.com/ReviewActivity',
'cookiepolicy': 'single_host_origin'
};
var renderBtn = function () {
gapi.signin.render('renderMe', options);
}
</script>
</head>
<body onload ="renderBtn()">
<div id="renderMe"></div>
</body>
</html>
Could I ask why the Windows 7 ASP.NET Javascript code works okay but not the AngularJS code version?
You have to point $window.location.href at a file in the Windows filesytem which conforms to JavaScript origin naming convention.

How do I search the rotten tomatoes API with AngularJS

I'm trying to create a search of the rotten tomatoes api using angularjs. I want to be able to type the query press enter or go (on a phone) then the api returns the result of the query.
I tried to attach the $scope.search to an input in the view. I know I'm doing something wrong but due to my inexperience I can't think what to do. Looking for someone to kindly point me in the right direction.
View
<input placeholder="Search for it" ng-model="search">
Controller
ctrls.controller('resultsCtrl', function($scope, $http){
$scope.search = 'query';
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/movies.json', {
params: {
page_limit: '5',
page: '1',
q: $scope.search,
apikey: myKey,
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.results = data.movies;
});
});
You will have to use a function for that
ctrls.controller('resultsCtrl', function($scope, $http){
$scope.search = 'query';
$scope.fetchResults = function(){
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/movies.json', {
params: {
page_limit: '5',
page: '1',
q: $scope.search,
apikey: myKey,
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.results = data.movies;
});
}
});
and call it from your view
<form ng-submit="fetchResults()">
<input placeholder="Search for it" ng-model="search">
<input type="submit" value="Go"/>
</form>