External API Call Using Express - api

I'm trying to call a College Score Card API using Express and Request. When I search for a specific school, I receive results from several schools, but not the school I searched for. Here is part of my code:
var fields = '_fields=school.name,2013.aid.median_debt.completers.overall,2013.repayment.1_yr_repayment.completers,2013.earnings.10_yrs_after_entry.working_not_enrolled.mean_earnings&page=100';
var requestUrl = 'https://api.data.gov/ed/collegescorecard/v1/schools.json?api_key=' + apiKey + '&' + fields;
module.exports = function(app) {
app.get('/school', function(req, res, next) {
request(requestUrl, function (error, response, body) {
if (!error && response.statusCode == 200) {
var json = JSON.parse(body);
console.log(json);
} else {
console.log("There was an error: ") + response.statusCode;
console.log(body);
}
});
})
};
HTML:
<form action="/school" method="GET">
<input type="text" class="form-control" name="school_name" value="" id="enter_text">
<button type="submit" class="btn btn-primary" id="text-enter- button">Submit</button>
</form>

You need to incorporate the school name into the URL. From your form that is set for method=GET, the name will come in req.query.school_name. So, instead of just sending the request to requestUrl, you send it to:
requestUrl + "&school_name=" + req.query.school_name
which will add this onto the end of the URL:
&school_name=Pepperdine
Or, put into your code, it would look like this:
module.exports = function(app) {
app.get('/school', function(req, res, next) {
request(requestUrl + "&school_name=" + req.query.school_name, function (error, response, body) {
if (!error && response.statusCode == 200) {
var json = JSON.parse(body);
console.log(json);
res.send(...); // send some response here
} else {
console.log("There was an error: ") + response.statusCode;
console.log(body);
res.send(...) // send some response here
}
});
})
};

Related

Square Payment SDK not taking amount from form

I have setup the Square SDK but I am having issue now, It is not taking the custom Input field value in processor file.
Here are my Codes,
<!DOCTYPE html>
<html>
<head>
<link href="css/app.css" rel="stylesheet" />
<script
type="text/javascript"
src="https://sandbox.web.squarecdn.com/v1/square.js"
></script>
<script>
const appId = 'sandbox-XXXXX-XXXXXXXXX';
const locationId = 'XXXXXXXXXXXXXX';
async function initializeCard(payments) {
const card = await payments.card();
await card.attach('#card-container');
return card;
}
async function createPayment(token) {
const body = JSON.stringify({
locationId,
sourceId: token,
});
const paymentResponse = await fetch('payment-process.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (paymentResponse.ok) {
return paymentResponse.json();
}
const errorBody = await paymentResponse.text();
throw new Error(errorBody);
}
async function tokenize(paymentMethod) {
const tokenResult = await paymentMethod.tokenize();
if (tokenResult.status === 'OK') {
return tokenResult.token;
} else {
let errorMessage = `Tokenization failed with status: ${tokenResult.status}`;
if (tokenResult.errors) {
errorMessage += ` and errors: ${JSON.stringify(
tokenResult.errors
)}`;
}
throw new Error(errorMessage);
}
}
// status is either SUCCESS or FAILURE;
function displayPaymentResults(status) {
const statusContainer = document.getElementById(
'payment-status-container'
);
if (status === 'SUCCESS') {
statusContainer.classList.remove('is-failure');
statusContainer.classList.add('is-success');
} else {
statusContainer.classList.remove('is-success');
statusContainer.classList.add('is-failure');
}
statusContainer.style.visibility = 'visible';
}
document.addEventListener('DOMContentLoaded', async function () {
if (!window.Square) {
throw new Error('Square.js failed to load properly');
}
let payments;
try {
payments = window.Square.payments(appId, locationId);
} catch {
const statusContainer = document.getElementById(
'payment-status-container'
);
statusContainer.className = 'missing-credentials';
statusContainer.style.visibility = 'visible';
return;
}
let card;
try {
card = await initializeCard(payments);
} catch (e) {
console.error('Initializing Card failed', e);
return;
}
// Checkpoint 2.
async function handlePaymentMethodSubmission(event, paymentMethod) {
event.preventDefault();
try {
// disable the submit button as we await tokenization and make a payment request.
cardButton.disabled = true;
const token = await tokenize(paymentMethod);
const paymentResults = await createPayment(token);
displayPaymentResults('SUCCESS');
console.debug('Payment Success', paymentResults);
} catch (e) {
cardButton.disabled = false;
displayPaymentResults('FAILURE');
console.error(e.message);
}
}
const cardButton = document.getElementById('card-button');
cardButton.addEventListener('click', async function (event) {
await handlePaymentMethodSubmission(event, card);
});
});
</script>
</head>
<body>
<form id="payment-form">
<div id="card-container"></div>
<input type="hidden" name="amount" value="500">
<button id="card-button" type="button">Pay $1.00</button>
</form>
<div id="payment-status-container"></div>
</body>
</html>
And The Next Processing file is payment-process.php
<?php
require 'vendor/autoload.php';
use Square\SquareClient;
use Square\Environment;
use Square\Exceptions\ApiException;
use Square\Models\Money;
use Square\Models\CreatePaymentRequest;
use Square\Models\createPayment;
$client = new SquareClient([
'accessToken' => 'EAAAEKE_XXXXXXXXXXXXXXXXXXXXXXXXvs3LXwg0A8TTX2dN5cR5u',
'environment' => Environment::SANDBOX,
]);
$payments_api = $client->getPaymentsApi();
$data = json_decode(file_get_contents('php://input'), true);
$amount = $_POST['amount'];
$amount = $amount * 100;
$money = new Money();
$money->setAmount($amount);
$money->setCurrency('AUD');
$Current_User = 78;
$TransactionID = 'BZ_'.$Current_User.'-'.rand(0000,9999);
$create_payment_request = new CreatePaymentRequest($data['sourceId'], $TransactionID, $money);
$create_payment_request->setNote('Description of Amount');
$response = $payments_api->createPayment($create_payment_request);
if ($response->isSuccess()) {
echo json_encode($response->getResult());
} else {
echo json_encode($response->getErrors());
}
?>
I have tried it with $data['input'] as well as $_POST['amount']
But it always give error of INVALID_AMOUNT_MONEY But If I put the same amount directly in variable $amount = 500; It works perfect.
It is not taking value from the Payment form.

filter query param not working through axios get from my vue js application?

whenever a user types anything into the textfield, an axios get request to the url
http://sandbox4.wootz.io:8080/api/data/1/action/?filter={id}like'%TE%' is made and it is supposed to return back all the filtered results based on the search(what user has typed) as a response. But currently rather than returning the filtered results as a response it is giving out all results(non-filtered results).
NOTE: I have tested the above mentioned URL through postman by making a get request and it gave out the filtered results perfectly.Why is the same not happening through my application code?plz help
getAsyncDataAction: debounce(function(name) {
if (!name.length) {
this.dataAction = [];
return;
}
this.isFetching = true;
api
.getSearchData(this.sessionData.key,`/action/?filter={id}like'%${name}%'`)
.then(response => {
this.dataAction = [];
response.forEach(item => {
this.dataAction.push(item);
});
console.log('action results are'+JSON.stringify(this.dataAction)) //displays all the results(non-filtered)
})
.catch(error => {
this.dataAction = [];
throw error;
})
.finally(() => {
this.isFetching = false;
});
}, 500),
api.js
import axios from 'axios';
const props = {
base_url: '/api/store',
search_url: '/api/entity/search',
cors_url: 'http://localhost',
oper_url: '/api'
};
axios.defaults.headers.get['Access-Control-Allow-Origin'] = props.cors_url;
axios.defaults.headers.post['Access-Control-Allow-Origin'] = props.cors_url;
axios.defaults.headers.patch['Access-Control-Allow-Origin'] = props.cors_url;
async function getSearchData(key, path) {
try {
console.log('inside getSearchData path value is'+path)
console.log('inside getSearchData and url for axios get is '+props.base_url + '/data' + path)
let response = await axios({
method: 'get',
url: props.base_url + '/data' + path,
headers: {'session_id': key}
});
if (response.status == 200) {
console.log(response.status);
}
return response.data;
} catch (err) {
console.error(err);
}
}
The problem is that you're not encoding the query string correctly. In particular, your % signs need to become %25
To do this, I highly recommend using the params options in Axios.
For example
async function getSearchData(key, path, params) { // 👈 added "params"
// snip
let response = await axios({
method: 'get',
url: `${props.base_url}/data${path}`,
params, // 👈 use "params" here
headers: {'session_id': key}
});
and call your function with
const params = {}
// check for empty or blank "name"
if (name.trim().length > 0) {
params.filter = `{id}like'%${name}%'`
}
api
.getSearchData(this.sessionData.key, '/action/', params)
Alternatively, encode the query parameter manually
const filter = encodeURIComponent(`{id}like'%${name}%'`)
const path = `/action/?filter=${filter}`
Which should produce something like
/action/?filter=%7Bid%7Dlike'%25TE%25'

Is there a way to fix Cannot read property 'post' of undefined?

I'm running a page in vue with a form, it submits and returns data to and from an API, I'm getting a 'post' of undefined error in the console and I can't seem to figure out what's going on.
<script>
methods: {
StartClient: function () { // Initiate XMLHttpRequest as aHttpRequest for GET
this.get = function(Url, Callback){
var aHttpRequest = new XMLHttpRequest();
aHttpRequest.onreadystatechange = function() {
if (aHttpRequest.readyState == 4 && aHttpRequest.status == 200)
Callback(aHttpRequest.responseText);
}
// use aHttpRequest with response headers, to allow GET
aHttpRequest.open("GET", Url, true);
aHttpRequest.setRequestHeader("X-Api-Key", "eVnbxBPfn01kuoJIdfgi46TiYNv8AIip1r3WbjsX");
aHttpRequest.send(null);
}
this.post = function(Url, message, Callback) { // initiate XMLHttpRequest as aHttpRequest for POST
var aHttpRequest = new XMLHttpRequest();
aHttpRequest.onreadystatechange = function() {
if (aHttpRequest.readyState == 4 && aHttpRequest.status == 200)
Callback(aHttpRequest.responseText);
}
// use aHttpRequest with response headers, to allow POST
aHttpRequest.open("POST", Url, true);
aHttpRequest.setRequestHeader("X-Api-Key", "eVnbxBPfn01kuoJIdfgi46TiYNv8AIip1r3WbjsX");
aHttpRequest.send(message);
}
},
submitData: function () { // Start a traceroute, followed by the 'Begin' button
document.getElementById('inputBox').disabled = true;
var targetInputButton = document.getElementById("inputBox").value;
var message = '{"targetInputButton":"' + targetInputButton + '"}';
this.StartClient().post('https://le75bkfcmg.execute-api.eu-west-2.amazonaws.com/dev/start-trace', message, function(response) {
document.getElementById('jobId').innerHTML = response;
});
},
sendBackData: function () { // Receive traceroute data, followed by the 'Generate data' button
var jobId = document.getElementById("jobId").innerHTML;
var message = '{"jobId":"' + jobId + '"}';
this.StartClient().post('https://le75bkfcmg.execute-api.eu-west-2.amazonaws.com/dev/check-trace', message, function(response) {
document.getElementById('report').innerHTML = response;
});
}
}
}
</script>

Angular 2 / 4 - How to know if API is Online?

I have a NodeJS Express API with this route http://localhost:4040/online
returning :
{
"status": "true"
}
if my API is online.
In my Angular 2 (4) application, I want to know in real time if my API is Online true or Online False.
I try many things but I cant get the status in real time, I need do call some service method. Is there a way to do that ?
UPDATE
This is my new code https://gist.github.com/duard/05283f1625c807f50ebc5cfb289e7ae4
It works, but I see in my console it trying to check the URL every 5 seconds ... I'm not happy yet :-(
OLD CODE
My Application
export class AppComponent {
title = 'app works!';
data: any[];
constructor(private http: Http, private apiService: ApiService) {
this.apiService.getData().subscribe(
data => {
this.data = data;
},
error => {
this.data = [{status: "false"}] ;
});
}
}
My service
export class ApiService {
private url: string = `http://localhost:4040/online`;
private data: any[];
private observable: Observable<any>;
constructor(private http: Http) { }
getData() {
console.log('getData called');
if (this.data) {
console.log('data already available');
// if `data` is available just return it as `Observable`
console.log(' => ' + ' pegou cache');
return Observable.of(this.data);
} else if (this.observable) {
console.log('request pending');
// if `this.observable` is set then the request is in progress
// return the `Observable` for the ongoing request
return this.observable;
} else {
console.log('send new request');
let headers = new Headers();
headers.append('Content-Type', 'application/json');
// create the request, store the `Observable` for subsequent subscribers
this.observable = this.http.get(this.url, {
headers: headers
})
.map(response => {
console.log('response arrived');
// when the cached data is available we don't need the `Observable` reference anymore
this.observable = null;
if (response.status == 400) {
return "FAILURE";
} else if (response.status == 200) {
this.data = response.json();
return this.data;
}
// make it shared so more than one subscriber can get the result
})
.share();
return this.observable;
}
}
}
My Template
<h1>
{{title}}
</h1>
<hr>
<h3>capitol</h3>
{{ capitol | json}}
<h3>data</h3>
{{ data | json}}
{{ (data | async) | json}}
<hr>
If I use this ASYNC I get errors.

Connect-busboy - Amazon S3 - Validation and return

I am trying to directly upload files from the browser to Amazon S3 using connect-busboy with the following code (https://github.com/thaume/s3-streaming)
route - index.js:
var awsUpload = require('../services/aws-streaming');
// Index route
// ===========
exports.index = function(req, res){
if (req.method === 'POST') {
return awsUpload(req, function(err, url) {
res.send(JSON.stringify(url));
});
}
res.writeHead(200, { Connection: 'close' });
res.end('<html><head></head><body>\
<form method="POST" enctype="multipart/form-data">\
<input type="file" name="filefield"><br />\
<input type="submit">\
</form>\
</body></html>');
};
with my modified version of aws-streaming.js
// Initialize aws client
// =====================
var config = require('../config/' + 'development');
var Knox = require('knox');
var moment = require('moment');
var crypto = require('crypto');
// Create the knox client with your aws settings
Knox.aws = Knox.createClient({
key: config.aws.AWS_ACCESS_KEY_ID,
secret: config.aws.AWS_SECRET_ACCESS_KEY,
bucket: config.aws.S3_BUCKET_NAME,
region: 'eu-west-1'
});
// S3 upload service - stream buffers to S3
// ========================================
var s3UploadService = function(req, next) {
req.files = {};
req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
if (!filename) {
// If filename is not truthy it means there's no file
return;
}
//////////////// CHECK FOR MIMETYE /////////////////////
// If file is not "text/plain" - return //
if (mimetype != "text/plain") {
console.log('true!')
return; // A JSON array with an error "Wrong file type"!
}
// Create the initial array containing the stream's chunks
file.fileRead = [];
file.on('data', function(chunk) {
// Push chunks into the fileRead array
this.fileRead.push(chunk);
});
file.on('error', function(err) {
console.log('Error while buffering the stream: ', err);
});
file.on('end', function() {
// Concat the chunks into a Buffer
var finalBuffer = Buffer.concat(this.fileRead);
req.files[fieldname] = {
buffer: finalBuffer,
size: finalBuffer.length,
filename: filename,
mimetype: mimetype
};
// Generate date based folder prefix
var datePrefix = moment().format('YYYY[/]MM');
var key = crypto.randomBytes(10).toString('hex');
var hashFilename = key + '-' + filename;
var pathToArtwork = '/artworks/' + datePrefix + '/' + hashFilename;
var headers = {
'Content-Length': req.files[fieldname].size,
'Content-Type': req.files[fieldname].mimetype,
'x-amz-acl': 'public-read'
};
Knox.aws.putBuffer( req.files[fieldname].buffer, pathToArtwork, headers, function(err, response){
if (err) {
console.error('error streaming image: ', new Date(), err);
return next(err);
}
if (response.statusCode !== 200) {
console.error('error streaming image: ', new Date(), err);
return next(err);
}
console.log('Amazon response statusCode: ', response.statusCode);
console.log('Your file was uploaded');
next();
});
});
});
req.busboy.on('error', function(err) {
console.error('Error while parsing the form: ', err);
next(err);
});
req.busboy.on('finish', function() {
console.log('Done parsing the form!');
// When everythin's done, render the view
next(null, 'http://www.google.com');
});
// Start the parsing
req.pipe(req.busboy);
};
module.exports = s3UploadService;
What I would like to do is to validate the mimetype and return a json array with the error message, ending the parsing of the form and not upload the file. Have added code to aws-streaming, but it will not return even if validates to true. What have I done wrong?
Also the code runs the callback when it is finished parsing the form, but I would like it to be run when the file is actually uploaded. How can I achieve this, comment out the next() in 'finish' event and move it to the Knox.aws.putBuffer?
Im using Express 4