Send http request in Ionic with Angular http - angularjs

I have an ionic app that I am trying to send my Stripe token to, for payment processing. When I send the request to the node server with curl it is receiving the request. However, when I try to send the request via Angular's http module, it isn't registering at all. All of this is currently being tested locally, so that might be part of the issue?
HTML
<button (click)="testPost()" ion-button full>TEST POST</button>
cart.ts
...
import {Http, Headers, RequestOptions} from '#angular/http';
import { Stripe } from '#ionic-native/stripe';
#Component({
selector: 'page-cart',
templateUrl: 'cart.html',
})
export class Cart {
constructor(
...
private http: Http,
private stripe: Stripe
) {
//
});
}
testPost() {
var headers = new Headers();
headers.append("Accept", 'application/json');
headers.append('Content-Type', 'application/json' );
let options = new RequestOptions({ headers: headers });
let postParams = {
body: {
token: 'axqrexample123tokenbasdflkjo3',
amount: 225
}
}
this.http.post("http://11.1.1.7:3100/charge", postParams, options)
.subscribe(data => {
console.log(data['_body']);
}, error => {
console.log(error);// Error getting the data
});
}
}
NODE SERVER
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var stripe = require("stripe")("sk_test_abcTAdefgn1oDexamplex");
app.use(bodyParser.json());
app.post('/charge', function (req, res) {
var token = req.body.token;
var amount = req.body.amount;
stripe.charges.create({
amount: amount,
currency: "usd",
source: token, // obtained with Stripe.js
description: "Charge for jones#example.com"
}, function(err, charge) {
// asynchronously called
});
res.send('Hello World!')
});
app.listen(3100, function () {
console.log('Example app listening on port 3100!')
})

I think you need to map the request before subscribing to the request
this.http.post("http://11.1.1.7:3100/charge", postParams, options)
.map(res => res.json())
.subscribe(data => {
console.log(data['_body']);
}, error => {
console.log(error);// Error getting the data
});
also, import the rxjs
import 'rxjs/Rx';

I would try this in the stripe.charges.create callback and see what happens:
}, function(err, charge) {
if (err) throw err;
console.log('Charge ID:', charge.id);
res.send('Hello World!');
});

Related

Axios React cors issue on product

my third party axios requests works properly on local mode properly thanks to "http-proxy-middleware", but after i build and deploy it, axios requests gives homepage html as response.
setupProxy.js file
const { createProxyMiddleware } = require("http-proxy-middleware")
const cors=require("cors")
const express = require('express');
const app = express();
module.exports=app=>{
app.use(
createProxyMiddleware("/api",
{
target:"third-party-api-url",
secure:false,
changeOrigin:true
})
)
ApiFrontend.jsx file
const [apiData,setApiData]=useState("")
var data = JSON.stringify({
"MERCHANT": "****",
"MERCHANT_KEY": "*******************************"
});
var config = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data : data
};
useEffect(()=>{
axios("/api",config)
.then(function (response) {
setApiData(response.data);
})
.catch(function (error) {
console.log(error);
});
},[])
i tried node server with express and use;
app.use(cors({
origin: API_URL,
credentials: true
}));
but it gives the same response

Axios Post from react to express proxy server

I have created an express server in which I am implementing a graphQL request. The following block of code was taken from postman snippets of a successful request
const express = require("express"),
app = express(),
port = process.env.PORT || 4000,
cors = require("cors");
var axios = require('axios');
var data = JSON.stringify({
query: `mutation claimTask ($taskId: String!, $assignee: String) {
claimTask (taskId: $taskId, assignee: $assignee) {
id
name
taskDefinitionId
processName
creationTime
completionTime
assignee
variables {
id
name
value
previewValue
isValueTruncated
}
taskState
sortValues
isFirst
formKey
processDefinitionId
candidateGroups
}
}`,
variables: {"taskId":"22","assignee":"demo"}
});
var config = {
method: 'post',
url: 'http://[my_ip]/graphql',
headers: {
'Authorization': 'Bearer ey....',
'Content-Type': 'application/json',
'Cookie': 'TASKLIST-SESSION=..'
},
data : data
};
app.use(cors());
app.listen(port, () => console.log("Backend server live on " + port));
app.post("/api", (req, res) => {
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
res.send({ message: JSON.stringify(response.data) });
})
.catch(function (error) {
console.log(error);
res.send({ message: error });
});
})
Currently I am calling this request from a react app with a button like this:
Axios({
method: "POST",
url: "http://localhost:4000/api",
headers: {
"Content-Type": "application/json"
}
}).then(res => {
console.log(res.data.message);
});
For the next step I want to pass the variables from my react app instead of writing them directly as string to express. What is the right approach to achieve this?
I am using the express server to avoid cors related issues.
Any suggestions can be useful, thank you!
So you want to send an Axios POST from react. Something along those lines should work:
const handleSubmit = (e) => {
e.preventDefault();
const variables = {
taskId: ”22”,
userId: “demo”
};
axios.post("http://localhost:4000/api", variables).then((response) => {
console.log(response.status);
});
};
Inspired by https://blog.logrocket.com/understanding-axios-post-requests/

React-native: Problem sending log - console.error

I'm working with Expo React native, I'm trying to send POST request to my express server using axios
App.js - in my React
Axios({
url:'http://172.20.1.19:3001/api/tracking/locator',
method:'POST',
data:{
test:'wew'
},
config:'JSON',
headers:{
"Access-Control-Allow-Origin": "*"
}
})
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
In node status its 200, but when console.log the response it throws an error
console.error. "There was a problem sending log message to your
development environment",
Tracking.js - Express
var express = require('express');
var cors = require('cors');
var router = express.Router()
const app = express();
const db = require('../models');
app.use(cors({origin:'http://172.20.1.19:19001'}));
router.get('/', function(req, res, next){
res.json({
data: {
test :'wew'
}
})
})
router.post('/locator', function(req,res,next){
res.json({
data:{
status:'pano mo nasabe'
}
})
})
module.exports = router
Try to use:
(this helped me)
console.log(JSON.stringify(response.data))
or
console.log(response.data)
also
console.log(JSON.stringify(response))

Trying to fetch API I created to react component

So I created test API and added few test records to the DB.
Now when I wanted to fetch the data in react component I'm getting this error
Unhandled Rejection (SyntaxError): Unexpected token < in JSON at position 0
when I try to console.log the data to see if it works. I asume it has something to do with the fact, that I run the API server on port 8080 and react app on 3000 (when I switched api to 3000 and clicked "back arrow" I saw a console.log with the data, but when I refreshed the site it realised the API is "occupying" this URL now).
How can I fix that? Here is the important part of the code, if I need to post more please do let me know.
API (app\src\apiTest\index.js):
const express = require('express');
const routes = require('./api.js');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const app = express();
//connect to mongodb
mongoose.connect('mongodb://localhost/drugDB');
mongoose.Promise = global.Promise;
//serving files (folder name)
app.use(express.static('../../../src'));
app.use(bodyParser.json());
//initialize routes
app.use('/api', routes);
//error handling middleware
app.use(function(err, req, res, next){
res.send({error: err.message})
})
app.listen(process.env.port || 8080, function(){
console.log('listening')
})
2nd file in API
const express = require('express');
const Drug = require('./models/drug');
const router = express.Router();
//get list of drugs
router.get('/leki', function (req, res) {
Drug.find({}).then(function(drugs){
res.send(drugs);
})
})
router.post('/leki', function (req, res, next) {
Drug.create(req.body).then(function (drug) {
res.send(drug);
}).catch(next);
})
router.put('/leki/:id', function (req, res, next) {
Drug.findByIdAndUpdate({ _id: req.params.id }, req.body).then(function () {
Drug.findOne({ _id: req.params.id }).then(function (drug) {
res.send(drug);
})
})
})
router.delete('/leki/:id', function (req, res, next) {
Drug.findByIdAndRemove({ _id: req.params.id }).then(function (drug) {
res.send({ type: drug })
});
})
module.exports = router;
react component (app\src\components\MainPanel\panel.js):
componentDidMount(){
fetch('/api/leki').then(function(data){
console.log(data.json());
})
}
The error is suggesting that you're not receiving JSON back in response. Which is the case because inside of your leki endpoint you're using res.send(drug); which sends data back as HTML, change it to res.json({data: drug}) and then inside of componentDidMount:
componentDidMount(){
fetch('/api/leki', {
method: 'GET',
headers: {
'Accept': 'application/json',
}
}).then(function(response){
return response.json();
}).then(function(data) {
console.log(data.drug)
})
}
Try this:
componentDidMount() {
fetch('/api/leki')
.then(function (resolve) { return resolve.json(); })
.then(function (resolveJson) {
console.log(resolveJson);
});
}
Look at this for more information:
https://developers.google.com/web/updates/2015/03/introduction-to-fetch
You need to allow Cross Origin requests by setting a header in your response in the backend.
Place this code where you send your response:
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');

Ionic http requests with authorization headers

I am sending a get request to the server and it requires a JWT token to authenticate. However Ionic insists on doing a pref-etch request without one and crashing. (Also is there any way to capture non 200 responses? the server gives a lot of those (e.g. 403 {message: Account Invalid}))
Code
auth.ts
import { Headers, RequestOptions } from '#angular/http'
import 'rxjs/add/operator/toPromise';
...
export const getToken = function(http){
return new Promise((resolve, reject) => {
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Authorization', 'JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjU4Yzg1MmI1YmQ1NjE1MGJkMDAxZWEzNyIsImlhdCI6MTQ4OTY3ODE0NywiZXhwIjoxNDg5NjgxNzQ3fQ.zUWvBnHXbgW20bE65tKe3icFWYW6WKIK6STAe0w7wC4');
let options = new RequestOptions({headers: headers});
http.get('//localhost:3000/auth/users', {headers: options})
.toPromise()
.then(res => resolve(res))
.catch(err => console.log(err));
});
}
Chrome console:
Response for preflight has invalid HTTP status code 401
Server sees: (I logged out the request and there are no headers or body)
OPTIONS /auth/users 401 25.613 ms - -
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Toast, Device } from 'ionic-native';
import { Http, Headers } from '#angular/http';
let headers = new Headers();
headers.append('Token', this.Token);
headers.append('id', this.ID);
this.http.get(this.apiUrl + this.yourUrl, { headers: headers })
.map(res => res.json())
.subscribe(
data => {
console.log(data);
if (data.code == 200) { // this is where u r handling 200 responses
if (data.result.length > 0) {
for (let i = 0; i < data.result.length; i++) {
var userData = {
username: data.result[i].username,
firstName: data.result[i].firstName,
lastName: data.result[i].lastName,
}
console.log(JSON.stringify(userData));
this.Results.push(userData);
}
}
}
else { // here non 200 responses
console.log(data.message);
}
this.user= this.Results;
console.log(this.user);
},
err => {
console.log("ERROR!: ", err);
});
this way u will be able to handle all responses from backend
I hope this works for you
To anyone else having this issue. devanshsadhotra's answer is great but here is the way I solved this issue:
ionic.config.json (add all the relevant routes here)
"proxies": [
{
"path": "/api",
"proxyUrl": "http://localhost:3000/api"
},
{
"path": "/auth",
"proxyUrl": "http://localhost:3000/auth"
}
]
Your networking file (auth.js in this case)
import { Headers } from '#angular/http' //Headers need to be in this object type
import 'rxjs/add/operator/toPromise'; //turns observable into promise
export const getToken = function(http){ //passing in the Http handler to the function for no good reason. but it works
return new Promise((resolve, reject) => { //return a promise to the calling function so it can handle the response
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Authorization', 'JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjU4Yzg1MmI1YmQ1NjE1MGJkMDAxZWEzNyIsImlhdCI6MTQ4OTY4MjY2MywiZXhwIjoxNDg5Njg2MjYzfQ.tW8nT5xYKTqW9wWG3thdwf7OX8g3DrdccM4aYkOmp8w');
http.get('/auth/users', {headers: headers}) //for post, put and delete put the body before the headers
.toPromise() //SANITY!!!
.then(res => resolve(res)) //Things went well....
.catch(err => console.log(err)); //Things did not...
});
}

Resources