Api call is not happening while calling Http Request using HttpClient in angular 7 - xmlhttprequest

I am converting a post API request written in javascript to typescript, but my new code seems to be not running as i do not see any network calls in the debugger. Please find my code snippets below.
javascript (working)
private resourcesAccessable(url, token, clientId, resources) {
var request = new XMLHttpRequest();
request.open('POST', url, false);
request.setRequestHeader("Authorization", "Bearer " + token);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
console.log(request);
var response ;
request.onreadystatechange = function () {
if (request.readyState == 4) {
var status = request.status;
if (status >= 200 && status < 300) {
response = JSON.parse(request.responseText);
} else if (status == 403) {
console.log('Authorization request was denied by the server.');
return null;
} else {
console.log('Could not obtain authorization data from server.');
return null;
}
}
}
var params = "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&response_mode=permissions&audience="+clientId;
if(Array.isArray(resources)){
for (var i = 0; i < resources.length; i++) {
params = params+"&permission="+resources[i]
}
}
request.send(params);
console.log(response);
return response;
}
typescript (not working)
resourcesAccessable(url, token, clientId, resources) {
private http: HttpClient,
private payload
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + token
})
};
this.payload = new URLSearchParams();
this.payload.set('grant_type','urn:ietf:params:oauth:grant-type:uma-ticket');
this.payload.set('response_mode','permissions');
this.payload.set('audience', clientId);
this.payload.set('permission',resources);
return this.http.post(url, payload.toString(), httpOptions)
.pipe(
tap(
(data) => {
console.log('----->>>', data);
}
)
), error => {
console.log('error ' + JSON.stringify(error));
};
}
I have tried many things to run the above code but none of them worked for me.

Split your code into the following sections. Angular/RxJS is different from vanilla JavaScript. You create Observable http calls which the Subscriber then reads from.
Inject HttpClient into your class -- necessary for http calls to work. (Needs additional dependencies to work. Please refer https://angular.io/guide/http)
constructor(protected http: HttpClient) {}
Function Definition
resourcesAccessable(url, token, clientId, resources): Observable<any> {
const payload = new URLSearchParams()
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + token
})
}
payload.set('grant_type', 'urn:ietf:params:oauth:grant-type:uma-ticket')
payload.set('response_mode', 'permissions')
payload.set('audience', clientId)
payload.set('permission', resources)
return this.http.post(url, payload.toString(), httpOptions)
}
Function Call
this.resourcesAccessable('', '', '', '')
.subscribe(
(data) => {
console.log('----->>>', data);
}
, error => {
console.log('error ' + JSON.stringify(error));
},
() => console.log('Completed'));

Related

How to use Spotify 30sec previews with Expo React native app

I have been trying to use the Spotify API in my expo app but every tutorial or wrapper I find doesn't seem to work.
I would specifically like to access the 30-second song previews and track/song searching features.
If anyone could provide some guidance or point me towards a working demo of any kind that would be awesome.
Thanks!
Found parts of the solution in https://docs.expo.dev/guides/authentication/#spotify
const discovery = {
authorizationEndpoint: 'https://accounts.spotify.com/authorize',
tokenEndpoint: 'https://accounts.spotify.com/api/token',
};
var client_id = ''; // Your client id
var client_secret = ''; // Your secret
export default function spotifyLogin(props) {
const [request, response, promptAsync] = useAuthRequest(
{
clientId: '',
scopes: ['user-read-email', 'user-read-playback-state', 'playlist-modify-public','playlist-modify-private','playlist-modify-public','playlist-read-private','user-read-recently-played'],
// In order to follow the "Authorization Code Flow" to fetch token after authorizationEndpoint
// this must be set to false
usePKCE: false,
redirectUri: makeRedirectUri({
//scheme: 'your.app'
}),
},
discovery
);
React.useEffect(() => {
if (response?.type === 'success') {
const { code } = response.params;
//save code to local storage
props.saveLogin(code)
}
}, [response]);
return (
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();
}}
/>
);
}
export const getFirstTokenData = async (code) => {
var dataToSend = {
code: code,
redirect_uri: makeRedirectUri(),
grant_type: 'authorization_code'};
//making data to send on server
var formBody = [];
for (var key in dataToSend) {
var encodedKey = encodeURIComponent(key);
var encodedValue = encodeURIComponent(dataToSend[key]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
//POST request
var response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
},
})
try{
return await response.json()
}catch (error){
console.log(error)
}
}
export const getRefreshTokenData = async (refreshToken) => {
console.log(refreshToken)
console.log(refreshToken + " going in for refresh")
var dataToSend = {
refresh_token : refreshToken,
grant_type: 'refresh_token'};
//making data to send on server
var formBody = [];
for (var key in dataToSend) {
var encodedKey = encodeURIComponent(key);
var encodedValue = encodeURIComponent(dataToSend[key]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
//POST request
var response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
},
})
try{
return await response.json()
}catch (error){
console.log(error)
}
}
The above takes care of auth and getting refresh tokens, below takes care of searching for a track. To get 30 second previews there is a preview property in the return data for getTrack()
const apiPrefix = 'https://api.spotify.com/v1';
export default async ({
offset,
limit,
q,
token,
}) => {
const uri = `${apiPrefix}/search?type=track&limit=${limit}&offset=${offset}&q=${encodeURIComponent(q)}`;
console.log('search begin, uri =', uri, 'token =', token);
const res = await fetch(uri, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
}
});
const json = await res.json();
//console.log('search got json', json);
if (!res.ok) {
return [];
}
return json
// const {
// tracks: {
// items,
// }
// } = json;
// // const items = json.tracks.items;
// return items.map(item => ({
// id: item.id,
// title: item.name,
// imageUri: item.album.images
// ? item.album.images[0].url
// : undefined
// }));
console.log('search end');
};
export const getTrack = async(trackID, token) => {
const uri = `${apiPrefix}/tracks/${trackID}?market=ES`;
const res = await fetch(uri, {
method: 'GET',
headers: {
// Accept: `application/json`,
// Content-Type: `application/json`,
Authorization: `Bearer ${token}`,
}
});
const json = await res.json();
//console.log('search got json', json);
if (!res.ok) {
return [];
}
return json
}
Once upon a time, I worked on a similar application as a test. It's a bit outdated, but I believe Spotify has not changed its API much in the meantime.
Hope this caa help
https://github.com/kubanac95/spotify-test

Is there any way to catch the response data which is causing the POST 400 (Bad Request) for Vue js fetch api?

I am sending post request from an array by looping through all indexes one by one.
function apiService(endpoint, method, data) {
// D.R.Y. code to make HTTP requests to the REST API backend using fetch
const config = {
method: method || "GET",
body: data !== undefined ? JSON.stringify(data) : null,
headers: {
'content-type': 'application/json',
'X-CSRFTOKEN': CSRF_TOKEN
}
};
return fetch(endpoint, config)
.then(handleResponse)
.catch(error => console.log(error))
}
let len = this.rowObject.length;
for (var i = 0; i <len; i++) {
apiService(endpoint, method, this.rowObject[i]);
}
I want to catch the this.rowObject[i] object or the i index which causes bad 400 request.
Can it be done using try catch?
You can inject an error handler that captures the information you want, like with onError below.
function apiService(endpoint, method, data, onError) {
// D.R.Y. code to make HTTP requests to the REST API backend using fetch
const config = {
method: method || "GET",
body: data !== undefined ? JSON.stringify(data) : null,
headers: {
'content-type': 'application/json',
'X-CSRFTOKEN': CSRF_TOKEN
}
};
return fetch(endpoint, config)
.then(handleResponse)
.catch(onError)
}
let len = this.rowObject.length;
for (var i = 0; i <len; i++) {
let onError = error => console.log("Error on rowObject " + i + ": " + error);
apiService(endpoint, method, this.rowObject[i], onError);
}

How to send data through API in Flutter?

When I try to login (email and password parameter) through APIs, data passes in row format, but I want to post data in form format.
Because of this problem, when I pass data it does not accept parameter value and shows null and gives error.
So, how can I solve this problem?
> This _loginUser() method In call on login button click.
_loginUser(context) async {
Map<String, dynamic> loginBodyResponse = {
"email": _emailController.text,
"password": _passswordController.text,
};
try {
setState(() {
_isLoading = true;
});
> APIs call
Map loginResponse = await NetworkHttp.postHttpMethod(
'${AppConstants.apiEndPoint}${AppConstants.loginApi}',
loginBodyResponse);
print('email:' + _emailController.text);
print('Password:' + _passswordController.text);
print(loginBodyResponse);
print('===================Login Response=========================');
print(loginResponse['body']);
print(loginResponse['body']['login']);
print("---------------------------");
if (loginResponse['body']['status'] != "success") {
setState(() {
_isLoading = false;
});
String errormessage = loginResponse['body']['msg'];
print("---------------------------");
print(errormessage);
ErrorDialog.showErrorDialog(context, errormessage, "Error");
} else {
print("Login Successfully");
print("============================================");
setState(() {
_isLoading = false;
});
NavigatorHelper.verifyOtpScreen(context);
}
} catch (e) {
setState(() {
_isLoading = false;
});
ErrorDialog.showErrorDialog(context, e.toString(), "Error");
print('error while login $e');
}
}
NetworkHttp class which I used in above mention code. when I try to login it shows null parameter in console
class NetworkHttp {
static Future<Map<String, String>> _getHeaders() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String token = prefs.getString('token');
if (token != null) {
return {
'Content-type': 'application/json',
'Accept': 'application/json',
'AccessToken': '$token',
};
} else {
return {
'Content-type': 'application/json',
'Accept': 'aapilcation/json',
};
}
}
static Future<Map<String, dynamic>> postHttpMethod(String url, body) async {
print('url');
print(url);
print('body');
print(body);
Map headers = await _getHeaders();
print('headers');
print(headers);
http.Response response = await http.post(
url,
headers: headers,
body: json.encode(body),
);
Map<String, dynamic> responseJson = {
'body': json.decode(response.body),
'headers': response.headers
};
return responseJson;
}
Just add headers with the json_data .
Future<login> requestLogin(String username, String password , String device_id) async {
Map<String, String> headers = {"Content-type": "application/x-www-form-urlencoded"};
var json_body = { 'email' : username , 'password': password ,'device_id': device_id};
if(token != null){
headers.addAll({"Authorization" : "Bearer "+token});
}
// make POST request
final response = await http.post(baseUrl+ "/login", headers: headers, body: json_body);
print(response.body);
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON.
// return Post.fromJson(json.decode(response.body));
print(response.body);
return login.fromJson(json.decode(response.body));
} else {
// If that response was not OK, throw an error.
throw Exception(response.body);
}
}
With your post request just pass your parameters like this
your post request should look something like below.
response = await http.post("your_api_url",
body:{"email" : "value",
"password" : "value"});

How to pass authorization token in header for GET method using XMLHttpRequest in react native

I am new to react-native. I am trying to pass the authorization token through a header in the GET method. But I am getting an unauthorized error.
I have already tried this code "Using an authorization header with Fetch in React Native" not working for me and also with XMLHttpRequest()
But the API works fine in postman, Java(core) and Android.
Do we have any special implementation in react-native to pass headers?
Could anyone can help me with this?
My code: Changed the server name.
getData() {
var data = null;
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("GET", "https://xyz-test-server.server.com/api/v3/users/details/");
xhr.setRequestHeader("Authorization", "Basic cC5qYWltdXJ1Z2FuLm1jYUBnbWFpbC5jb206MTIzNDU2");
xhr.setRequestHeader("User-Agent", "PostmanRuntime/7.17.1");
xhr.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=ISO-8859-1");
xhr.setRequestHeader("Accept", "*/*");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Postman-Token", "d8ae56bf-1926-44e4-9e94-23223234,93a110a2-ee8e-42d5-9f7b-45645ddsfg45");
xhr.setRequestHeader("Accept-Encoding", "gzip, deflate");
xhr.setRequestHeader("Connection", "keep-alive");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
}
Fetch method:
async _getProtectedQuote() {
fetch('https://xyz-test-server.server.com/api/v3/users/details/', {
method: 'GET',
headers: new Headers({
'Authorization': 'Basic cC5qYWltdXJ1Z2FuLm1jYUBnbWFpbC5jb206MTIzNDU2',
'Content-Type': 'application/x-www-form-urlencoded'
}),
}).then(responseJson => {
alert(JSON.stringify(responseJson));
console.log(responseJson);
});
}
You can try interceptor for pass token into header.
Put all requests in one service file name service.js then import Interceptor from '../interceptor';
make one interceptor.js file and write below code in file.
import axios from 'axios';
axios.interceptors.request.use(async (config) => {
if (config.method !== 'OPTIONS') {
config.headers.Authorization = 'Basic cC5qYWltdXJ1Z2FuLm1jYUBnbWFpbC5jb206MTIzNDU2';
}
return config;
}, function (error) {
// Do something with request error
console.log('how are you error: ', error);
return promise.reject(error);
});
axios.interceptors.response.use(
(response) => {
return response
},
async (error) => {
// const originalRequest = error.config
console.log("error in interceptors=============>", error);
if (error.response.status === 500) {
alert(error.response.data.message);
NavigationService.navigate('Login');
} else {
return Promise.reject(error)
}
}
)
export default axios;
When api calls header will pass through by interceptor automatically.
Fetch Api converts all headers into lower-case. We need to do case-insensitive server side parsing.

How to obtain access token from Yelp Fusion API using NodeJS

I am trying to obtain the access token for Yelp's API.
Yelp's API documentation:
https://www.yelp.com/developers/documentation/v3/get_started
I keep running into the error below on my terminal:
problem with request: getaddrinfo ENOTFOUND api.yelp.com/oauth2/token api.yelp.com/oauth2/token:80
Here's my NodeJS code (I took a lot of it from the Node Documentation site):
var http = require("http");
var postData = JSON.stringify({
"grant_type": "client_credentials",
"client_id": "<<client id>>",
"client_secret": "<<client secret no.>>"
});
var options = {
hostname: 'api.yelp.com/oauth2/token',
port: 80,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
var req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
Two items that caught my eye:
Separate the hostname and the path in your options variable.
The YELP Fusion API is HTTPS, not HTTP. Using HTTP may result in a 302 response (URL Redirection).
var https = require('https');
getYelpAccessCode(function(response) {
var responseData = JSON.parse(response);
if (responseData != null) {
var accessCode = responseData.token_type + " " + responseData.access_token;
}
});
function getYelpAccessCode(callback) {
const postData = querystring.stringify({
'client_id': YELP_CLIENT_ID,
'client_secret': YELP_CLIENT_SECRET
});
const options = {
hostname: 'api.yelp.com',
path: '/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
const req = https.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
var body = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
body += chunk;
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
callback(body);
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
}