ngAutoComplete with Google Suggest api - javascript

AngularJS has ngAutoComplete that works with Google place perfectly.
How can I make it work with Google Suggest API (the suggested keywords when typing in Google Search input box)? Is there something out of the box?
If not, what is the best way to implement it? (if I need my own API interface - how should I make the connection)?
EDITED
Google Suggest API will return XML for the following call. If I want to return JSON it needs to be passed via my server side to translate it. It could also be an option if you suggest so
http://google.com/complete/search?output=toolbar&q=theory&gl=in

You can add this to the remote-url -
https://www.google.com/s?sclient=psy-ab&biw=1242&bih=395&q=ThisIsTheSearchString&oq=&gs_l=&pbx=1&bav=on.2,or.r_cp.&bvm=bv.93112503,d.cWc&fp=160df26a97fa030e&pf=p&sugexp=msedr&gs_rn=64&gs_ri=psy-ab&tok=_1hxlqgFnvRgVdHXR4t-nQ&cp=10&gs_id=51&xhr=t&es_nrs=true&tch=1&ech=37&psi=O5FTVZiMAfPisASwnYH4Cg.1431540027601.1
Make ThisIsTheSearchString a var that changes on key stroke. Before you put the url into the ngAutoComplete make sure to encode the string - escape(ThisIsTheSearchString); This will help if there are any white spaces in the search.
I got the URL by going to google and watching the network tab. It will return a .txt file that you will have to read. Also you will need a regex to compile the file.

Updated Version (Custom Directive ngGoogleSuggest)
click Plunker
Directive performs much better because on keyup performs a http call to GoogleSuggest API
elem.bind('keyup', scope.search);
Markup:
<div data-ng-google-suggest ng-model="Search"></div>
Note: I plan to make a GitHub repo for ngGoogleSuggest after it has been tested a bit more
Screen Shots
Calling Google Search API
End Point: 'http://suggestqueries.google.com/complete/search
for JSON response (not XML), add param &client=firefox
Uri Encoded search Parameter
use JSONP protocol by adding ?callback=JSON_CALLBACK to avoid Access-Control-Allow-Origin Error
example $http call
scope.search = function() {
// If searchText empty, don't search
if (scope.searchText == null || scope.searchText.length < 1)
return;
var url = 'http://suggestqueries.google.com/complete/search?';
url += 'callback=JSON_CALLBACK&client=firefox&hl=en&q='
url += encodeURIComponent(scope.searchText);
$http.defaults.useXDomain = true;
$http({
url: url,
method: 'JSONP',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).
success(function(data, status, headers, config) {
// Api returns [ Original Keyword, Searches[] ]
var results = data[1];
if (results.indexOf(scope.searchText) === -1) {
data.unshift(scope.searchText);
}
scope.suggestions = results;
scope.selectedIndex = -1;
}).
error(function(data, status, headers, config) {
console.log('fail');
// called asynchronously if an error occurs
// or server returns response with an error status.
});

Related

devops-rest APi - $expand not working for "Work Items - Get Work Items Batch"

I want to access some data from selected work items.
Below is my working code.
function postApiData(ApiUrl, responseBody, token) {
var res = '';
$.ajax({
type: 'POST',
async: false,
url: ApiUrl,
contentType: 'application/json',
data: JSON.stringify(responseBody),
cache: false,
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa("" + ":" + _token));
},
}).done(function (data) {
res = data;
});
return res;
};
var d = {
"ids": itemlist,
"fields": ["System.Id", "System.WorkItemType", "System.Title", "System.AssignedTo", "System.State", "System.Tags", "cust.PID", "cust.Product", "cust.ReleasedToProduction"]
};
var itemdata = postApiData('https://dev.azure.com/COMP/products/_apis/wit/workitemsbatch?$expand=relations&api-version=5.1', d, '');
However, $expand is not working here to get relations. query gives the result and always ignores $expand.
I have also tried to pass $expand in request body, but it is also not working. Can anyone please guide here?
That's because the expand parameter can not be used with the fields parameter if the expand value is relations.
You could execute this api with your request body in Postman. You will get the clearly message that why you can not apply it.
To use your API, if you specify the fields in the request body, then expand should not be used any more, and vice versa. This is as designed, and it has been hardcoded into our scripts. We do not allow another $expand value if it is not the None or Links.
For the 5 values of $expand(None, Relations, Fields, Links, All), only None and Links can work with fields successfully in API. This is a universal rule which apply to all APIs, including this one.
Also, please use $expand=Relations in request body instead of in URI which shown as the document described. Here if you use it in URI, it will not be used by server script since the method that this API called does not has this parameter. Another API which can use $expand in the URI (As normal, we would mention and show whether it can be used in URI in document), the corresponding scripts have parameters can access these value which passed by URI.
So, here please use $expand=Relations in request body, then you would get the result with all fields and its all relations.

Invalid input response and secret when verifying google reCaptcha

I am really struggling to get a successful response when doing a post request to the google recaptcha api. I am receiving the following response:
{
"success": false,
"error-codes": [
"invalid-input-response",
"invalid-input-secret"
]
}
I had a look at reCAPTCHA - error-codes: 'missing-input-response', 'missing-input-secret' when verifying user's response (missing details on POST) and followed the answer as closely as possible but with no success.
Here is my file below:
var request = require('request');
module.exports = {
verifyCaptcha: function(req, res) {
var secret = 'SECRET_KEY';
var response = JSON.stringify(req.body.response);
request({
url: 'https://www.google.com/recaptcha/api/siteverify',
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `secret=${secret}&response=${response}`,
}, function (err, response, body) {
if (err) {
res.status(500).send({
error: "Could not verify captcha"
});
} else {
res.status(200).send({
message: body
});
}
});
},
}
If anyone has a solution to this problem please let me know!
Due to the docs: https://developers.google.com/recaptcha/docs/verify
invalid-input-secret: The secret parameter is invalid or malformed.
Maybe you have mixed the site_key and the secret_key.
You need to add the user remote IP address.
var user_ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
request({
url: 'https://www.google.com/recaptcha/api/siteverify',
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `secret=${secret}&response=${response}&remoteip=${user_ip}`}...
Another thing I see that you are not using template literal, you should change the quotes to ` instead of '.
OR, You should use a ready-made module for reCaptcha, like this one:
https://www.npmjs.com/package/recaptcha
For reCAPTCHA Enterprise, check the official docs: https://cloud.google.com/recaptcha-enterprise/docs/create-assessment.
In short, you need to use the library that Google provides:
const { RecaptchaEnterpriseServiceClient } =
require('#google-cloud/recaptcha-enterprise');
const client = new RecaptchaEnterpriseServiceClient();
const [ response ] = await client.createAssessment({...});
RecaptchaEnterpriseServiceClient requires a service account to be created beforehand as described here. The key for that account with the right roles set can then be read by the app. Check the arguments of the constructor to see the available options to pass the data if the file cannot be retrieved automatically.
var response = JSON.stringify(req.body.response);
The stringifying here is probably the cause of the invalid-input-response error.
If your body is something like {"g-recaptcha-response": "..."}, you need to pull out the response value and pass that directly in your post.
Regarding invalid-input-secret, if you have set up your key and secret through the classic interface at https://www.google.com/u/1/recaptcha/admin/create, then you shouldn't have a problem.However if you set up a key with recaptcha Enterprise on Google Cloud, then it requires that you do Oauth authentication to the Google Cloud API and then use the create.assessment endpoint to get back information on the validity of the user. As Yuuhn implied, the Google provided library makes interaction with recaptcha Enterprise easier, without a lot of documentation digging to find where your REST API calls need to go.

Cross domain HTML parsing using AngularJS [duplicate]

This question already has an answer here:
Why does my JSONP request give me Uncaught SyntaxError: Unexpected token < (less than)?
(1 answer)
Closed 5 years ago.
We are working on java project in which backend is java + spring and fronted is angular 2 + HTML.
I want to do cross domain html parsing but we don't have permission to access external links on server side as we have some security issues for outsite domains, so we have to get the DOM content of link on client side using jquery.
I have tried these:
var url = "http://xyz.aspx";
$http({
method: 'JSONP',
url: url,
params: {
format: 'jsonp',
json_callback: 'JSON_CALLBACK'
}
}).
success(function(response) {
$scope.test = response;
}).
error(function(status) {
//your code when fails
});
The external link which I need to parse contains many href links. I also need to parse content of those links.
Have tried above mentioned code:
getting error in console - Uncaught SyntaxError: Unexpected token < on
xyz.aspx page
What will be best solution to get content of the pages and pass to server side for parsing?
Solution 1)
getting error in console - Uncaught SyntaxError: Unexpected token < on xyz.aspx page
This means that the server callback isn't a valid JavaScript application. Please ensure your server returns a valid JavaScript application. In that way this error will go away. JSONP needs a valid JavaScript application response to make it work. For example this is how a JSONP callback should look like:
jsonCallback(
{
sites: [
{
siteName: "Test"
}
]
}
);
Solution 2)
If your server side does not return a JSON Object try to use a GET request and enable CORS.
$http({
method: 'GET',
url: "http://xyz.aspx",
}).success(function(response) {
$scope.test = response.data;
}).error(function(status) {
//your code when fails
});
Solution 3)
If you are still be unable to add CORS to your backend you could create an PROXY application yourself. This for example is an public CORS Proxy https://crossorigin.me/. Adding an example on how to create a proxy service would be to much. Please research by yourself. There are a lot of examples in the web.
See ng.$http. Your URL is missing the callback parameter,instead of giving like
json_callback: 'JSON_CALLBACK'
Try below way
$http({
method: 'jsonp',
url: 'http://xyz.aspx?callback=JSON_CALLBACK',
params: { name: 'xyz' }
}).success(function(data, status , header, config) {
console.log('success');
}).error(function(data, status , header, config) {
console.log('error');
});

Angular HTTP GET request returns undefined while working in browser

I'am learning AngularJs and I've tried to write a very basic script sending an http request to Ebay public API, I've signed up and got my API keys, I've read the docs several times and wrote this basic code :
$scope.getQueryUrl = function () {
// Some unrelated code ...
$scope.queryUrl["Ebay"] = "http://svcs.sandbox.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-NAME=FindingService&SERVICE-VERSION=1.0.0&GLOBAL-ID=EBAY-US&SECURITY-APPNAME="+dataAuth.EbayKeyApi+"&RESPONSE-DATA-FORMAT=XML&keywords="+$scope.qtext ;
};
$scope.sendRequest = function () {
$scope.getQueryUrl(); // Gets the query url after adding all the parameters
alert($scope.queryUrl.Ebay);
$http.get($scope.queryUrl["Ebay"]).then(
function(response){
alert("success" + response.data );
},
function(response){
alert("error" + response.statusCode );
});
};
How this code should work :
It should create a formated Ebay query url, send it through HTTP GET request and sending back the response .
Note : $scope.qtext & dataAuth.EbayKeyApi are already assigned with their respective values .
What's the problem:
The problem is that using this Angularjs script, the code doesn't work, the alert "Error" is shown, and the response.statusCode is undefined .
But when I copy the formatted Ebay query link in Firefox it works perfectly and the XML response is shown .
The formatted Ebay query was generated using the script provided .
I think it's a header related problem .
$http has some default headers defined. $http sends Json payload and accepts Json as the response by default. Since you are dealing with XML you have to explicitly specify the accepted response type as XML using the header:
Accept: application/xml
Please use the following function with appropriate headers and you should get the response. Also, please look into any Cross Origin Resource Sharing (CORS) restrictions on the ebay API.
function getRequest(url) {
$http({
method: "GET",
url: url,
headers: {
'Content-Type': 'application/xml, text/xml',
'Accept': 'application/xml, text/plain, * / *'
}
})
.then(function (response) {
alert(response.data);
},
function (error) {
alert (error);
});
}
Thank you,
Soma.

Vimeo API request with AngularJs "401 Authorization required"

I've been trying to call an external API (Vimeo) from my AngularJS code, using $http.jsonp. But all i get is a 401 Authorization required even though i added my authorization Key to the header. had a similar problem doing the same thing with jQuery.ajax(). But with jQuery i solved the problem by setting the beforeSend function to set my authorization key on the request Header using the xhr object.
My code:
function(){
var config = {
headers: {Authorization: "bearer 34210aeac4e02a251b8821a53620e93c"},
params : {
callback: 'JSON_CALLBACK'
}
};
var url = "https://api.vimeo.com/tags/fun/videos?per_page=5";
$http.jsonp(url, config).success(function(response){
console.log(response);
});
};
How do i get this to work. Is the some kind of config.beforeSend that i can use to set the header just like jQuery
In angular you could use http interceptor
Define your http interceptor: this one will add a token on every http request
ng.module('interceptors')
.factory('authorizationInterceptor', function () {
return {
request: function (config) {
config.headers = config.headers || {};
config.headers.Authorization = 'Bearer ' + '34210aeac4e02a251b8821a53620e93c';
return config;
}
};});
register your interceptor
angular.module('myApp',[]).config(['$httpProvider',function ($httpProvider) {
$httpProvider.interceptors.push('authorizationInterceptor');
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);
Note, I think the first letter of bearer must be capital letter in you header
I don't know Angular too well, but I think the issue is that you're using JSONP. Since that uses the browser's script tag to get around CORS restrictions, it does not allow for verbs other than GET nor setting headers.
The Vimeo API supports CORS headers, so you actually want to make a regular GET request using the browser's AJAX functionality. I believe that AngularJS provides for this with the $http.get function to do what you're currently doing (docs).
I would try out:
function(){
var config = {
headers: {Authorization: "Bearer 34210aeac4e02a251b8821a53620e93c"}
};
var url = "https://api.vimeo.com/tags/fun/videos?per_page=5";
$http.get(url, config).success(function(response){
console.log(response);
});
};

Categories

Resources