So I'm new in angular and I'm new with API's
I tried to create thingy, where I can get video information by id, using several tutorials and browsing stackoverflow
I managed to find 2 solutions to the problem, but neither of them work for me.
First I tried
mvcApp.service('ApiCall', ['$http', function($http) {
var result;
this.GetApiCall = function() {
result = $http.get('https://hosting.com/webmasters/video_by_id?id=123456789')
.success(function(data) {
result = (data);
})
.error(function() {
alert('Something wrong');
});
return result;
}}]);
It uses good API link, but return No 'Access-Control-Allow-Origin' header is present on the requested resource error.
Next solution I found was:
mvcApp.factory('json', function($http) {
return {
getInformation: function (name) {
var url = 'https://hosting.com/webmasters/video_by_id';
return $http.jsonp(url, {
params: {
id: name
}
});
}
}});
This one returns errors, as it does not recognises var as a link, and return video_by_id?id=123456789:1 Uncaught SyntaxError: Unexpected token : error. But as I tinkered with it and looked at some other examples, found out that adding extension to links, fixes this, but I do not have or know an extension. So any help would be valuable
If your API is not in the same server as your Angular code, you could handle CORS on the requested resource, to avoid the error.
Related
I am confused why this is happening. I am fairly new with AngularJS/JS so bear with me. I want to create a simple side project that will assist me in learning how to cook, so I am using a recipe database API caled Yummly that will GET recipes with ingredients and other information.
Here's the documentation: https://developer.yummly.com/documentation.
I tried putting api key and ID in the URL as the API said I can. I also tried putting it in the HTTP headers as the API also said I could. I tried both in postman and both worked, but neither work in my code. I get the error:Cannot GET /[object%20Object]. So I am lost. Perhaps this description from the "How to use GET method" from the documentation is the reason?:
Don’t forget to URL-encode parameter names and values (i.e., [ and ] become %5B and %5D). I don't understand this preceding sentence so...
Here's my code. Thanks so much. Much appreciated!
angular.module("app", [])
.controller('AppController', ['$scope', '$http', function ($scope, $http) {
$scope.greeting = 'Hola!';
$scope.getRecipe = function(){
$http.get({
url: 'http://api.yummly.com/v1/api/recipes?q=onion+soup',
method: 'GET',
headers: {
'X-Yummly-App-ID':'myID (secret)',
'X-Yummly-App-Key':'myKey (secret)'
}
}).success(function(response) {
console.log("I got the response.");
}).error(function(error) {
console.log("failed", error);
})
}
}]);
If $http.get is preferred, the code would be:
$http.get('http://api.yummly.com/v1/api/recipes', {
params: {
q: 'onion+soup'
}
headers: {
'X-Yummly-App-ID':'myID (secret)',
'X-Yummly-App-Key':'myKey (secret)'
}
}).success(function(response) {
console.log("I got the response.");
}).error(function(error) {
console.log("failed", error);
})
According to the official document, the syntax of $http.get is:
get(url, [config]);
Shortcut method to perform GET request.
The first parameter of $http.get is a URL string. If an object is passed (as in the question), it would be converted to string, that's why you get the request sent to /[object%20Object] -- [object%20Object] is the toString() result of the config object.
Don’t forget to URL-encode parameter names and values (i.e., [ and ] become %5B and %5D). I don't understand this preceding sentence so...
Don't worry. This will be handled automatically. If the value of q above is 'onion+soup[xxx]', it would be URL-encoded as 'onion%2Bsoup%5Bxxx%5D'.
This may be a silly question and I am very new to NativeScript. I have a sample project up. Trying to do a simple get request to a local api. This is a website setup on my local dev machine for:
http://test-api.dev/api/v1
I am trying to access an endpoint on my local API and it does not seem to return ANYTHING. But I can change the API endpoint to something that is not a local API and sometimes it return stuff.
The API is a Laravel/PHP api and I can confirm it is infact returning valid json, so I don't think the API is the problem. Here is my file.
var config = require("../../shared/config");
var fetchModule = require("fetch");
//var http = require("http");
var ObservableArray = require("data/observable-array").ObservableArray;
function GroceryListViewModel(items) {
var viewModel = new ObservableArray(items);
viewModel.load = function() {
// http.getJSON(config.apiUrl + "events").then(function(result) {
// console.log(JSON.stringify(result));
// }, function(error) {
// console.error(JSON.stringify(error));
// });
return fetch(config.apiUrl + "events", {
headers: {
//"Authorization": "Bearer " + config.token
"Content-Type": "application/json"
}
})
.then(handleErrors)
.then(function(response) {
console.log(response);
return response.json();
}).then(function(data) {
console.dump(data);
data.forEach(function(event) {
viewModel.push({
name: event.name,
id: event.id
});
});
});
};
viewModel.empty = function() {
while (viewModel.length) {
viewModel.pop();
}
};
return viewModel;
}
function handleErrors(response) {
if (!response.ok) {
console.log(JSON.stringify(response));
throw Error(response.statusText);
}
return response;
}
module.exports = GroceryListViewModel;
Please go easy on me, definitely seeking help on this though. Thank you all in advance.
return fetch(config.apiUrl + "events", { - so the fetch request is expecting the first argument to be a URL. So where config.apiUrl is defined is where the request goes. You can change this to point to the localhost instance of your server you are running.
So I have found the issue, thought I would post it. The problem wasn't my endpoints or my NS install. It is because Android Emulators out of the box cannot reference local sites running on your dev machine without some modification to the hosts settings on the Emulator. This process is explained here but I want to emphasize for anyone having the same issue.
Android emulators do not support access to local machine sites out of the box as explained here: https://developer.android.com/studio/run/emulator-networking.html
It needs to be setup through the device EVERYTIME unless someone has a solution to set this up only once, I would love to see it shared here.
There are serveral solutions outlining similar steps but I have had issues on every single one. Here is one that outlines the gist of the issue:
http://sadhanasiblog.blogspot.in/2012/07/local-environment-setup-for-android.html
Thanks for the help.
I have to load a JSON file from another server (where I don't have control). After some hours researching found that JSONP is the dirty hack that answers mine pleads.
I am using nodejs, serving the site on localhost:3000 using gulp.
Loading the JSON from localhost:8000
I was able to get an example working, from an URL I do not need (found it randomly on the Internet), using the same code that I had not working with my URL.
That makes me wonder if I am trying to read the file like something it is not? As far as I could research it shouldn't be needed to parse a JSON into JSONP. Am I on the right track?
Underneath, the code which I was talking about:
(function () {
'use strict';
angular
.module('qwe.asd')
.controller('UsersController', UsersController);
/** #ngInject */
function UsersController($http, $log, $sce) {
var vm = this;
var trustedUsersAPI = "http://localhost:8000/users?callback=JSON_CALLBACK";
$sce.trustAsResourceUrl(trustedUsersAPI);
$http.jsonp(trustedUsersAPI, {
'callback': 'JSON_CALLBACK'
})
.success(function (data) {
$log.log("request 1 - OK");
$log.log(data);
vm.users = data;
})
.error(function () {
$log.log("request 1 - KO");
});
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";
$sce.trustAsResourceUrl(url);
$http.jsonp(url)
.success(function (data) {
$log.log("request 2 - OK");
$log.log(data);
})
.error(function () {
$log.log("request 2 - KO");
});
}
})();
And the logs generated...
angular.js:13424 request 1 - KO
angular.js:13424 request 2 - OK
angular.js:13424 Object {found: 12, posts: Array[12]}
And finally, the JSON files I am (mis)reading:
The one I need but I can't have
[{"id":0,"firstname":"front","lastname":"end","email":"frontend#example.com"},{"id":1,"firstname":"back","lastname":"end","email":"backend#example.com"},{"id":2,"firstname":"john","lastname":"doe","email":"johndoe#example.com"},{"id":3,"firstname":"dev","lastname":"eloper","email":"developer#example.com"},{"id":4,"firstname":"ad","lastname":"min","email":"admin#example.com"}]
And the one I don't need but works fine
{"found":12,"posts":[{"ID":XX,"site_ID":XXXX,"author":XXXX(..POSTS DATA WITH NO VALUE HERE..)}]}
P.S. I am really green here, I am on angular since this morning!
For those who come after me, I was following the wrong track. Thanks to the commenters I learnt that JSONP has to be supported on the server (just like CORS does).
I am trying to access an API using AngularJS. I have checked the API functionality with the following node code. This rules out that the fault lies with
var http = require("http");
url = 'http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10';
var request = http.get(url, function (response) {
var buffer = ""
response.on("data", function (chunk) {
buffer += chunk;
});
response.on("end", function (err) {
console.log(buffer);
console.log("\n");
});
});
I run my angular app with node http-server, with the following arguments
"start": "http-server --cors -a localhost -p 8000 -c-1"
And my angular controller looks as follows
app.controller('Request', function($scope, $http){
// functional URL = http://www.w3schools.com/website/Customers_JSON.php
$scope.test = "functional";
$scope.get = function(){
$http.get('http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10',{
params: {
headers: {
//'Access-Control-Allow-Origin': '*'
'Access-Control-Request-Headers' : 'access-control-allow-origin'
}
}
})
.success(function(result) {
console.log("Success", result);
$scope.result = result;
}).error(function() {
console.log("error");
});
// the above is sending a GET request rather than an OPTIONS request
};
});
The controller can parse the w3schools URL, but it consistently returns the CORS error when passed the asterank URL.
My app avails of other remedies suggested for CORS on this site (below).
Inspecting the GET requests through Firefox shows that the headers are not being added to the GET request. But beyond that I do not know how to remedy this. Help appreciated for someone learning their way through Angular.
I have tried using $http.jsonp(). The GET request executes successfully (over the network) but the angular method returns the .error() function.
var app = angular.module('sliderDemoApp', ['ngSlider', 'ngResource']);
.config(function($httpProvider) {
//Enable cross domain calls
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
You should understand one simple thing: even though those http modules look somewhat similar, they are totally different beasts in regards to CORS.
Actually, the node.js http.get() has nothing to do with CORS. It's your server that makes a request - in the same way as your browser does when you type this URL in its location bar and command to open it. The user agents are different, yes, but the process in general is the same: a client accesses a page lying on an external server.
Now note the difference with angular's $http.get(): a client opens a page that runs a script, and this script attempts to access a page lying on an external server. In other words, this request runs in the context of another page - lying within its own domain. And unless this domain is allowed by the external server to access it in the client code, it's just not possible - that's the point of CORS, after all.
There are different workarounds: JSONP - which basically means wrapping the response into a function call - is one possible way. But it has the same key point as, well, the other workarounds - it's the external server that should allow this form of communication. Otherwise your request for JSONP is just ignored: server sends back a regular JSON, which causes an error when trying to process it as a function call.
The bottom line: unless the external server's willing to cooperate on that matter, you won't be able to use its data in your client-side application - unless you pass this data via your server (which will act like a proxy).
Asterank now allows cross origin requests to their API. You don't need to worry about these workarounds posted above any more. A simple $http.get(http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10')
will work now. No headers required.I emailed them about this issue last week and they responded and configured their server to allow all origin requests.
Exact email response from Asterank : "I just enabled CORS for Asterank (ie Access-Control-Allow-Origin *). Hope this helps!"
I was having a similar issue with CORS yesterday, I worked around it using a form, hopefully this helps.
.config(function($httpProvider){
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
})
.controller('FormCtrl', function ($scope, $http) {
$scope.data = {
q: "test"//,
// z: "xxx"
};
$scope.submitForm = function () {
var filters = $scope.data;
var queryString ='';
for (i in filters){
queryString=queryString + i+"=" + filters[i] + "&";
}
$http.defaults.useXDomain = true;
var getData = {
method: 'GET',
url: 'https://YOUSEARCHDOMAIN/2013-01-01/search?' + queryString,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
console.log("posting data....");
$http(getData).success(function(data, status, headers, config) {
console.log(data);
}).error(function(data, status, headers, config) {
});
}
})
<div ng-controller="FormCtrl">
<form ng-submit="submitForm()">
First names: <input type="text" name="form.firstname">
Email Address: <input type="text" ng-model="form.emailaddress">
<button>bmyutton</button>
</form>
</div>
Seems to work with the url you posted above as well..
ObjectA: 0.017DEC: 50.2413KMAG: 10.961KOI: 72.01MSTAR: 1.03PER: 0.8374903RA: 19.04529ROW: 31RPLANET: 1.38RSTAR: 1T0: 64.57439TPLANET: 1903TSTAR: 5627UPER: 0.0000015UT0: 0.00026
I should also add that in chrome you need the CORS plugin. I didn't dig into the issue quite as indepth as I should for angular. I found a base html can get around these CORS restrictions, this is just a work around until I have more time to understand the issue.
After lots of looking around. The best local solution I found for this is the npm module CORS-anywhere. Used it to create AngularJS AWS Cloudsearch Demo.
I'm doing the initialize as i'm supposed to, with the right keys etc.
Even when doing so right within the function that is later using Parse.Cloud.run, I still get 401 unauthorized.
Is there a way to see if the initialize worked properly?
does it return any kind of response? error? if so, how do I go about seeing said response?
the initialize is currently simply:
Parse.initialize("appid", "javascript key"); (with the correct keys of course).
then I call a cloud function:
Parse.Cloud.run('testfunction', aUserObj, {
success: function(result) {
supersonic.ui.dialog.alert(result);
},
error: function(error) {
supersonic.ui.dialog.alert(error);
}
});
and the error is 401 unauthorized (which I also see in the javascript console as POST api.parse.com..... 401 unauthorized).
btw - using curl and rest api key I can make it work without a problem, so it's not an actual permissions issue as best I can tell.
Thanks.
You are right #nopro
The problem is the parameter format which makes the whole request omit app and javascript key which results in 401 error.
Thank you
I was trying to call function like this:
Parse.Cloud.run('sendMessage', message, {
success: function(success) {
$scope.isLoading = false;
},
error: function(error) {
$scope.isLoading = false;
}
});
but I should have done it like this:
Parse.Cloud.run('sendMessage', {"message":message.id}, {
success: function(success) {
$scope.isLoading = false;
},
error: function(error) {
$scope.isLoading = false;
}
});