How to populate md-autocomplete dropdown list? - angularjs

I'm trying use md-autocomplete with $http(), I can see the values in the console, but I can't display the data returned from the api request to the autocomplete.
I tried using the return keyword to return values stored in the JSON array.
<md-autocomplete
md-autoselect=true
placeholder="Search for films"
md-items="item in querySearch(searchText)"
md-item-text="item.title"
md-min-length="2"
md-search-text="searchText"
md-selected-item="selectedItem">
<md-item-template>
<span class="films-title">
<span md-highlight-flags="^i" md-highlight-text="searchText">
{{item.title}}
</span>
</span>
</md-item-template>
<md-not-found>
No match found.
</md-not-found>
</md-autocomplete>
The data I want to display is stored in a JSON array and the contents can be seen in the console:
'use strict';
filmApp.controller('SearchController',function ($scope, $http){
$scope.results = {
values: []
};
$scope.querySearch = function (query) {
$http({
url: 'https://api.themoviedb.org/3/search/movie?include_adult=false&page=1',
method: 'GET',
params: {
'query': query,
'api_key': apiKey
}
}).success(function (data, status) {
for (var i = 0; i < data.results.length; i++) {
$scope.results.values.push({title: data.results[i].original_title});
console.log($scope.results.values);
return $scope.results.values;
}
console.log("STATUS: "+status);
}).error(function (error) {
console.log("ERROR: "+error);
});
};
});

querySearch method should return a promise & from the promise.then you should be returning a data. So in your case you used .success/.error callbacks(thought they are already deprecated) which is disallow promise to be return from your querySearch method
$scope.querySearch = function (query) {
return $http.get('https://api.themoviedb.org/3/search/movie?include_adult=false&page=1', {
params: {
'query': query,
'api_key': apiKey
}
}).then(function (data, status) {
var data= response.data;
for (var i = 0; i < data.results.length; i++) {
$scope.results.values.push({title: data.results[i].original_title});
console.log($scope.results.values);
}
return $scope.results.values;
})
};

Related

deffer.promise result wont display in typehead using service

i am using angularjs 1.7 and i am trying to display the result of the function using service in the typhead
<input type="text" id="oppId" name="oppId" aria-label="oppId"
ng-model="oppId"
typeahead="item for item in commonService.oppIdTypeAhead($viewValue) | limitTo:10"
ng-blur="checkAndValidate($event)">
oppIdTypeAhead: function (val) {
var deferred = $q.defer();
var config = {
method: "GET",
headers: { Accept: "application/json" },
url: constants.oppPickup,
params: {
oppID: val
},
timeout: this._getCanceler('OppTypeAhead')
};
$http(config).then(function (data) {
deferred.resolve(data.data);
}).catch(function (data, status, headers, config) {
if (status === 0 && data === null) {
deferred.reject('canceled');
} else {
deferred.reject(data);
}
});
console.log(deferred.promise);
return deferred.promise;
this is the result returned by promise
it should display the list of results
but then it has an exception of Object doesn't support property or method 'success'

Angularjs calling restful api (post) without success bad request

I have to call a restful API with basic auth "i think the auth is working)"
that needs this special custom header: "X-AppGlu-Environment: staging" I don't know how to put the header" then I need to post to one URL, data with this format:
Body:
{
"params": {
"stopName": "what you want search"
}
}
Let's see my code at moment "it's not structured yet"
controller:
'use strict';
angular.module('myApp', ['base64'])
.controller('transportController', function($scope, $http, $base64){
$scope.$watch('search', function() {
fetch();
});
function fetch(){
var data = {
"params": {
"stopName": $scope.search
}
}
$http.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
var encoded = $base64.encode("xxxx:xxxx");
$http.defaults.headers.common.Authorization = 'Basic ' + encoded;
$http.post("the url", data)
.then(function(response){ $scope.details = response.data; });
}
});
view:
<div class="input-group search-bar">
<input type="text" ng-model="search" ng-model-options="{ debounce: 800 }" onclick="select()" class="form-control" placeholder="Enter destiny" autofocus />
<span class="input-group-addon bar-style"><i class="glyphicon glyphicon-search"></i></span>
I receive a error 400 bad request when i try to search for something, i think is something with the format of the object i'm trying to send, but if is, i don't know what to change.
Is working now i changed to this structure
function fetch(){
var data = {
"params":{
"stopName": "%"+$scope.search+"%"
}
}
var encoded = $base64.encode("xxxx:xxxx");
$http({
url: "url",
headers : {
"X-AppGlu-Environment":"staging",
"Authorization": "Basic "+encoded,
"Content-Type" : "application/json; charset=utf-8"
},
method: 'POST',
data: {
"params":{
"stopName": "%"+$scope.search+"%"
}
}
}).then(function(response){
$scope.details = response.data.rows;
});
// $http.get("http://www.omdbapi.com/?s=" + $scope.search)
//.then(function(response){ $scope.related = response.data; });
}

AngularJs server request queue or function is not call

I've subscribed in my controller on socket event.
When some event has come, i need to get some data from server (i try to call lb.get() as a function into some factory).
$scope.counter = 0;
$scope.$on('lEvent', function (event, response) { // socket event
$scope.counter ++;
console.log('counter '+$scope.counter);
lb.get(response[0]).then(function(response){
var Item = {
id: response.id,
mime: response.mime,
name: response.name,
};
$scope.items.push(Item);
console.log("$scope.items"+$scope.items.length);
});
});
// here is a function in my factory
get: function(id) {
deferred = $q.defer();
$http({
method: "post",
url: url,
data: $.param({id: id}),
headers: header
})
.success(function (data) {
deferred.resolve(data);
})
.error(function (data) {
deferred.reject(data);
});
return deferred.promise;
}
Imagine, i've got 5 socket events, but function lb.get() has called a 4 (or 3) times instead of 5. You can see the result of calling in console:
As you can see, the function lb.get() was called 4 times instead of 5.
I think, i need something like a request queue.
You don't have handle for the error response method get. Maybe in this case, your response is disappear.
You don't need a request queue.
See example on jsfiddle.
angular.module('ExampleApp', [])
.controller('ExampleOneController', function($scope, ServiceExample) {
$scope.counter = 0;
$scope.successCounter = 0;
$scope.errorCounter = 0;
$scope.$on('raise.event', function(event, value) {
console.log('counter', $scope.counter);
$scope.counter++;
ServiceExample.get(value).then(function() {
console.log('success response:', $scope.successCounter);
$scope.successCounter++;
}).catch(function() {
console.log('error response:', $scope.errorCounter);
$scope.errorCounter++;
});
});
})
.controller('ExampleTwoController', function($scope) {
$scope.raiseValue = "www.google.com"
$scope.raise = function(val) {
$scope.$emit('raise.event', val);
};
})
.service('ServiceExample', function($http) {
return {
get: function(url) {
return $http({
method: "GET",
url: url
});
}
}
});
.errors {
color: maroon
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="ExampleApp">
<div ng-controller="ExampleOneController">
<h3>
ExampleOneController
</h3>
<form name="ExampleForm" id="ExampleForm">
<pre>counter : {{counter}}</pre>
<pre>successCounter: {{successCounter}}</pre>
<pre class="errors">errorCounter: {{errorCounter}}</pre>
</form>
<div ng-controller="ExampleTwoController">
<h3>
ExampleTwoController
</h3>
<form name="ExampleForm" id="ExampleForm">
<input ng-model="raiseValue">
<br>
<button ng-click="raise(raiseValue)" simple>
Send request to "{{raiseValue}}"
</button>
</form>
</div>
</div>
</body>

How to perform an ajax lookup within `ng-repeat`

I have an ng-repeat of employees. One of the result fields returned is an employee number e.g. "12345".
How can I perform an ajax lookup and replace the employee number with the corresponding name?
Example: /_api/web/lists/getByTitle('allStaff')/items?$select=fullName&$filter=userid eq '12345'
would return: "Doe, John".
I've tried using a filter but nothing ever gets displayed even though I can see results returned.
<div ng-repeat="emp in employees"">
<i class="fa fa-user"></i> {{emp.id}}
</div>
app.filter('getName', function($http) {
return function(id){
if (id) {
var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('allStaff')/items?$select=fullName&$filter=userid eq '"+id+"'";
$http({
method: 'GET',
url: url,
cache: true,
headers: { "Accept": "application/json;odata=verbose" }
}).success(function (data, status, headers, config) {
userInfo = data.d.results[0].pn;
console.log(userInfo);
}).error(function (data, status, headers, config) {
userInfo = "0";
});
return userInfo;
}
};
});
The filter function is synchronous, while the $http call is asynchronous. The success callback isn't even going to be executed until after the filter function has already returned, so it looks like the return value will be undefined.
An angular filter isn't really appropriate for loading data from an API, and there's an easier approach. Add userInfo to the employees array in the appropriate service/factory/controller (that's up to how you're organizing your code, but the controller where you set $scope.employees is the quick and dirty option). Something like a forEach through the array making an API call for each one and setting employee.userInfo in the success callback:
app.controller('EmployeeController', function($scope, $http) {
// $scope.employees is initialized somehow
$scope.employees.forEach(function (employee) {
if (employee.id) {
var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('allStaff')/items?$select=fullName&$filter=userid eq '"+employee.id+"'";
$http({
method: 'GET',
url: url,
cache: true,
headers: { "Accept": "application/json;odata=verbose" }
}).success(function (data) {
employee.userInfo = data.d.results[0].pn;
}).error(function () {
employee.userInfo = "0";
});
}
});
});
And in your template:
<div ng-repeat="emp in employees">
<i class="fa fa-user"></i> {{emp.userInfo}}
</div>
It's up to you to figure out what to do before the ajax request is finished, while emp.userInfo is undefined - hide the element, show a placeholder, etc.

Filter Array Using Angular

I am trying to filter an array (courses) by a property, FacilityId.
I am getting a response back for all of my $http calls in my controller which is as follows:
function holeIndexController($scope, $http) {
$scope.facilities = [];
$scope.courses = [];
$scope.holes = [];
getFacilities();
getCourses();
getHoles();
function getFacilities() {
$http({
method: 'GET',
url: '/api/facility'
}).
success(function(result) {
$scope.facilities = result;
}).error(function () {
console.log("Error: " + result.ExceptionMessage);
alert("Could not load facilities");
});
}
$scope.courseByFacility = function (facilities) {
return function(courses) {
return course.facilityId === facility.facilityId;
};
};
function getCourses() {
$http({
method: 'GET',
url: '/api/course'
}).
success(function (result) {
$scope.courses = result;
}).error(function (result) {
console.log("Error: " + result.ExceptionMessage);
alert("Could not load courses");
});
}
function getHoles() {
$http({
method: 'GET',
url: '/api/hole'
}).
success(function(result) {
getFacilities();
$scope.holes = result;
}).error(function(result) {
console.log("Error: " + result.ExceptionMessage);
alert("Could not load courses");
});
}
}
And my HTML is as follows:
<div data-ng-repeat="f in facilities">
Facility: {{f.Name}}
<div data-ng-repeat="c in courses | filter: coursesByFacility">
Course: {{c.Name}}
</div>
</div>
What is the best way to filter courses by their respective FacilityId's?
Pass the facility into the filter function, like:
<div ng-repeat="c in courses | filter:coursesByFacility(f)">
Also, your coursesByFacility function takes a courses parameter, but then you're trying to act upon course (no s). Change this to this:
$scope.coursesByFacility = function(facility) {
return function(course) {
return course.facilityId === facility.facilityId;
}
}
See this jsbin
Edit: Didn't realize the jsbin link was going to strip all the code so you can't see it. Anyways, just view the source, it's minimal and easy to read
You could create a function called getCoursesByFacility() which has a facilityId parameter. The function should iterate through the list of courses and build an array of courses with that facilityId, then return the list. You would then need to call the function from your javascript. Something like this should work:
<div data-ng-repeat="f in facilities">
Facility: {{f.Name}}
<div data-ng-repeat="c in getCoursesByFacility(f.facilityId)">
Course: {{c.Name}}
</div>
</div>

Resources