Angular async http autocomplete - javascript

I want to create an autocomplete with Angular and since this is my first contact with angular, I`m pretty stucked.
Here is my code:
MenuService.getAutocompleteData(term).then(function (response) {
$scope.menuData = response.data;
});
This is how I call a service that is making the following http call:
return $http({
url : autocompletePath,
method : "POST",
data : {
term: term
}
}).success(function (response) {
return response;
});
The problem is that it seems that is syncronously and my browser freezes when I type fast letters. I saw that it is about that ".then" promise, but I`m not sure how to fix it. Any help would be appreciated.

You do a HTTP-request, which is correct, but you try to return the result on success. Instead you should try to do what needs to be done in your success-handler.
So in your service you would do something like this:
return $http({
url : autocompletePath,
method : "POST",
data : {
term: term
}
}); //note that there is no success handler in your service, because what's supposed to happen when the request completes, is the controller's business, not the service's. The service should only know where to get the data
And you would change your controller to this:
MenuService.getAutocompleteData(term).success(function (response) {
$scope.menuData = response.data;
}); //note the success-handler

Why dont you give this a try?
https://angular-ui.github.io/bootstrap/#/typeahead

Related

AngularJS : injecting data from factory to controller

I trying to get some data and then pass it to the controller for further processing. I have setup a factory to get the data but having issues passing it to the controller and getting it working. Below is the case I'm working with.
var app = angular.module("contactApp",[]);
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
$http.get("/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID).success(onSuccess).error(onFailure);
}
};
});
app.controller('ContactController', function(listData,$scope){
//setTimeout(function(){console.log(Data)},2000);
console.log("Controller called. Hello");
listData.getData(successFunction,failFunction,curItemId);
successFunction = function(data){
$scope.resData = data;
console.log("Success - ", data);
}
failFunction - function(data){
console.log("Didn't work - ", data);
}
});
This gives me below error.
successFunction is not defined
Not sure what I'm doing wrong, any input will be greatly appreciated!
EDIT:
Moving the functions down works really well but the async call is failing. I switched to using $ajax and it works just fine but $http doesn't work for some reason!
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
//$http.get("/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20156").success(onSuccess).error(onFailure);
$.ajax({
url:"/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID,
headers: {"accept": "application/json; odata=verbose"},
success: onSuccess,
error: onFailure
});
}
};
});
Just fyi the data is coming from a SharePoint list but that shouldn't matter. I'll keep digging and please do let me know if I'm making any syntax error that I can't locate.
I really appreciate the help guys!
EDIT 2:
Ok this issue was unrelated. I found the problem, SharePoint uses odata so I had to pass a header:
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
$http(
{
method: "GET",
headers: {"accept": "application/json; odata=verbose"},
url: "/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID
}
).success(onSuccess).error(onFailure);
}
};
});
You guys ROCK!!!!!!!
As Daniel A. White said, declare your functions before you call them.
var app = angular.module("contactApp",[]);
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
$http.get("/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID).success(onSuccess).error(onFailure);
}
};
});
app.controller('ContactController', function(listData,$scope){
//setTimeout(function(){console.log(Data)},2000);
console.log("Controller called. Hello");
var successFunction = function(data){
$scope.resData = data;
console.log("Success - ", data);
}
var failFunction - function(data){
console.log("Didn't work - ", data);
}
//Now your functions are actually defined.
listData.getData(successFunction,failFunction,curItemId);
});
You don't have to use var to declare functions, because JavaScript will still understand but using var makes it a local variable, while not using var will define it as global.
I'm sure this will help.

How do I ng-watch a variable from a ViewModel and update it in the HTML?

I have a :
ng-click="like(photo.Id)"
...which fires a http post call to update data in the database.
The photo object comes from a ViewModel and can be accessed in the HTML by using ex {{photo.Likes}}. This.. gives me the number of likes and works like it should..
But.. I need to update the count in the html page when the ng-click="like...." function is clicked by the user.
So.. I am trying to do something like this :
<span ng-watch="{{photo.Likes}}"></span>
but clearly.. I don't understand well enough how this stuff works.
Here is the $http call which fills $scope.photo. Do i need to add some watch logic here too ?
$http({
method: 'GET',
url: '/api/ViewImage/GetPhotoById/' + $routeParams.id,
accept: 'application/json'
})
.success(function (result) {
console.log(result);
$scope.photo = result;
});
Do you mean:
<span>{{photo.Likes}}</span>
Just putting expression in the double mustaches like {{ photo.Likes }} makes a binding which will update your html once the value is updated.
Create a method for ng-click that will change the value (I think you got this part already)
So overall it going to be something like below:
<span ng-click='like(photo.photoId)'>like</span>
<span>{{photo.Likes}}</span>
And in controller:
....controller(function($scope, $http) {
$scope.photo = null
$scope.like = function(photo) {
photo.Likes++
}
$http({
method: 'GET',
url: '/api/ViewImage/GetPhotoById/' + $routeParams.id,
accept: 'application/json'
})
.success(function (result) {
console.log(result);
$scope.photo = result;
});
})
ng-watch as a directive, does not exist.
You need to create something within your controller, service, directive etc to use: $scope.$watch

angular.js call an ajax compatible WCF service

How can you call an ajax compatible WCF service inside a angular.js controller ?
I tried to combine Jquery and Angular.JS, something like :
app.controller('ListUsersController', function () {
var me = this;
this.listusers = [];
this.fill = function () {
$.getJSON("Contact.svc/getjemploye", function (data) {
me.listusers.push({id:"1",name:"Vinc"});
});
};
});
When I push the user inside the listusers, it look like the controller can't see I am adding something to the list, so it doesn't show the list again (In the html, I can't see the new user I just pushed).
Angular has its own set of Ajax callers.
$http({ method: "GET", url: "http://yoururlhere.com")
.success(function (response) {
alert("success!");
});

Calling service function from within the same service

I am trying to call a service method from within the same service but I am getting call to undefined function error. So I made a work around as shown below but still wondering how I can call the service function without using the work around. So can someone please help by telling me what I am missing here? Thanks
.factory('TestSvc', function($http, $q) {
return {
login: function(){
var checkStatusFunction = this.checkstatus; //This is the workaround to make it work...
$http({ method:'POST',
url: url
responseType: 'json'
}).success(function(data,status,headers,config){
//this.checkStatus(); //this will return error call to undefined
checkStatusFunction(); //this will work as it is the work around
}).error(function(data,status,headers,config){
});
},
checkStatus: function(){
}
}
});
A little bit less hacky would be:
var $this = this;
Instead of:
var checkStatusFunction = this.checkstatus;
And then call:
$this.checkstatus();

Angular $http bad request

Below I've got a function that should make a post to the server.
var updateApplicationMetadata = function(appId, editorVersion, previewPubFile){
var deferred = $q.defer();
var result = $http({
method: 'post',
url: '../resource/applications/'+appId,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
editorVersion: editorVersion,
previewPubFile: previewPubFile
}
});
result.then(function(data){
deferred.result(data);
console.log('from services: ');
console.log(data);
});
return deferred.promise;
};
I call this function like:
$scope.update = function(){
MessageBus.emitMsg('notification','Application updates successful.');
console.log('from update: ');
console.log($scope.application.appId);
console.log($scope.application.editorVersion);
console.log($scope.application.previewPubFile);
DataContext.updateApplicationMetaData($scope.application.appId,$scope.application.editorVersion ,$scope.application.previewPubFile);
};
All of the values sent to the updateApplicationMetaData are valid. I can use the rest client POST man and I can make the post work. When I do it in angular, however, I get a bad request. The URL and header content type are right, but I'm not sure about the data object. It must be malformed. What am I missing here?
You've got an error in your code. You have:
deferred.result(data);
and it should be:
deferred.resolve(data);
for it to work. Also, you need to pass 'application/json' as your accepts type for your data to work.
Assuming you are using the $q service from https://docs.angularjs.org/api/ng/service/$q I don't see a result method. Perhaps change:
deferred.result(data);
To
deferred.resolve(data);
consider using ngResource for rest style json requests
Angular resource docs

Categories