Fetch JSON data using Authorization header in D3 v5 - d3.js

I am working on some charts in d3.js v5.8.2 and I want to load JSON data that I get from an API request which needs an authorization header. I tried something like:
d3.json('url')
.header("Authorization", "Bearer 7tsBVpsiYT")
.get(function(error, data) {
// callback
console.log(data);
});
I get the following error message:
Uncaught TypeError: d3.json(...).header is not a function

Since D3 v5 uses the Fetch API as a replacement for the XMLHttpRequest which was used by prior versions the API for d3.json() needed to be changed a bit. From the docs:
# d3.json(input[, init]) <>
Fetches the JSON file at the specified input URL. If init is specified, it is passed along to the underlying call to fetch; see RequestInit for allowed fields.
You now have to pass the Authorization header via the RequestInit object which is passed as the optional second argument to d3.json(). As Mike Bostock explains in his basic demo Fetch with Basic Auth this can be done using the native Fetch API:
fetch("https://httpbin.org/basic-auth/user/passwd", {
headers: new Headers({
"Authorization": `Basic ${base64.encode(`${login}:${password}`)}`
}),
}).then(response => {
if (!response.ok) throw new Error(response.status);
return response.json();
});
Looking at the source of d3.json() one notices that above code is basically equivalent to what D3 does internally while executing d3.json. Thus, the code can be rewritten as:
d3.json("https://httpbin.org/basic-auth/user/passwd", {
headers: new Headers({
"Authorization": `Basic ${base64.encode(`${login}:${password}`)}`
}),
}).then(json => { /* do something */ });

Related

Receive & Respond to Twilio Text Message with Node js express graphql

I followed the Twilio instructions to setup receive & respond to a text message as in the URL below which uses a Rest Post. It works. Great.
app.post('/sms', (req, res) => {
// Start our TwiML response.
const twiml = new MessagingResponse();
// Add a text message.
const msg = twiml.message('Check out this sweet owl!');
// Add a picture message.
msg.media('https://demo.twilio.com/owl.png');
res.writeHead(200, {'Content-Type': 'text/xml'});
res.end(twiml.toString());
});
I then wanted to convert the REST POST to a graphql POST to be consistent with my code base. I set it up, and my graphql POST responds with the following format which is not xml (which I believe Twilio requires) but json as per graphql. Thus, I can see the response move through the system but Twilio registers an error. If I'm correct, is there a way for Twilio to process the graphql json response or for me to adjust graphql to return xml rather than json (as below)?
My latest graphql attempt wraps the rest post in a graphql query as such.
sms: async () => {
// console.log(request, response);
const { MessagingResponse } = require("twilio").twiml;
const twiml = new MessagingResponse();
twiml.message("The Robots are coming! Head for the hills!");
let test = "";
return axios({
method: "post",
url: "https://2b52-98-38-82-19.ngrok.io/sms",
responseType: 'text/xml'
})
.then(res => test = res.data)
// .then(function (response) {
// console.log('axios response =', response);
// return twiml.toString();
// })
.catch(function (error) {
console.log(error);
});
}
}
returning the following via Apollo Sandbox and/or insomnia.
{
"data": {
"sms": "<?xml version="1.0" encoding="UTF-8"?><Response><Message>The Robots are coming! Head for the hills POST POST!</Message></Response>"
}
}

How do I get a specific column name values using Axios Promise-based Http Request in Vue.js and Laravel 8

If I do this in my Vue.js script component
getResumeAPIData(id){
// declare a response interceptor
axios.interceptors.response.use((response) => {
// do something with the response data
console.log('Response was received');
return response;
}, error => {
// handle the response error
return Promise.reject(error);
});
// sent a GET request
axios.get(`api/resume-data-returns/${id}`)
.then((response)=>{
this.RelationTable = response.data
console.log(this.RelationTable);
})
},
I get a response like this
{"id":1,"name":"userlocalvm","email":"userlocalvm#v","email_verified_at":null,"type":"user","bio":"Why","photo":"1606931001.jpeg","created_at":"2020-12-02T16:01:00.000000Z","updated_at":"2020-12-02T17:43:21.000000Z"}
Because of my Laravel api.php->Controller Backend code
$findOrFailId = Resumes::findOrFail($forEachId);
$foreignKeyOfResTable = $findOrFailId->user_id;
return User::findOrFail($foreignKeyOfResTable);
But if I do it like this as
// sent a GET request
axios.get(`api/resume-data-returns/${id}`)
.then((response)=>{
this.RelationTable = response.data.created_at
console.log(this.RelationTable);
})
The added dot then the property name of the column
response.data.created_at
I get a response
undefined
Sorry if this is a silly question as I am still quite a rookie in programming in general and the jargons that comes with it and I want learn and master javascript and php so bad!
It might be that the response is inside another data object. You might have to do something like this:
response.data.data.created_at

Difficulty creating a functional Angular2 post

I'm trying to send a post request to another service (a Spring application), an authentication, but I'm having trouble constructing a functional Angular2 post request at all. I'm using this video for reference, which is pretty new, so I assume the information still valid. I'm also able to execute a get request with no problems.
Here's my post request:
export class LogIn {
authUser: string;
authPass: string;
token: any;
constructor(private _http:Http){}
onSubmit() {
var header = new Headers()
var json = JSON.stringify({ user: this.authUser, password: this.authPass })
var params2 = 'user=' + this.authUser + '&password=' + this.authPass
var params = "json=" + json
header.append('Content-Type', 'application/x-www-form-urlencoded')
this._http.post("http://validate.jsontest.com", params, {
headers: header
}).map(res => res.json())
.subscribe(
data => this.token = JSON.stringify(data),
err => console.error(err),
() => console.log('done')
);
console.log(this.token);
}
}
The info is being correctly taken from a form, I tested it a couple of times to make sure. I am also using two different ways to build the json (params and params2). When I try to send the request to http://validate.jsontest.com, the console prints undefined where this.token should be. When I try to send the request to the Spring application, I get an error on that side:
Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
Does anyone know what I'm doing wrong?
In fact you need to use the GET method to do that:
var json = JSON.stringify({
user: this.authUser, password: this.authPass
});
var params = new URLSearchParams();
params.set('json', json);
this._http.get("http://validate.jsontest.com", {
search: params
}).map(res => res.json());
See this plunkr: http://plnkr.co/edit/fAHPp49vFZJ8OuPC1043?p=preview.

Getting binary file content instead of UTF-escaped using file.get

I'd like to know if it's possible to get exact binary data using callback from drive.files.get method of NodeJS Google API. I know that object returned by calling this API endpoint is a normal request object that could be e.g. piped like this:
drive.files.get({
fileId: fileId,
alt: 'media'
}).pipe(fs.createWriteStream('test'));
However I would like to know if it's possible to get binary data from within callback using this syntax:
drive.files.get({
fileId: fileId,
alt: 'media'
}, function(err, data) {
// Here I have binary data exposed
});
As far as I know, it should be possible to get that kind of data from request during its creation, passing {encoding: null} in request options object like this:
var requestSettings = {
method: 'GET',
url: url,
encoding: null // This is the important part
};
request(requestSettings, function(err, data) {/.../})`
however it seems that Google obscures this configuration object in its library.
So my question is - is it possible to do so without interfering/hacking the library?
Ok, so i found answer that could be useful for others :)
Aforementioned drive.files.get method returns Stream object, so it could be directly handled using proper event handlers. Then, buffer parts could be concatenated into one part and sent back in callback like this:
var stream = drive.files.get({
fileId: fileId,
alt: 'media'
});
// Build buffer
var chunks = [];
stream.on('data', (chunk) => {
chunks.push(chunk);
});
stream.on('end', () => {
return cb(null, Buffer.concat(chunks));
});

Django Posts Not Working:

I am using Django 1.2.3 to develop a site. My ajax get requests work fine but the post requests work in development mode (127.0.0.1:8000) but not when I push the site into production using apache + nginx.
Here is an example
urls.py:
(r'api/newdoc/$', 'mysite.documents.views.newdoc'),
views.py
def newdoc(request):
# only process POST request
if request.is_ajax():
data= dict(request.POST)
# save data to db
return HttpResponse(simplejson.dumps([True]))
in javascript:
$.post("/api/newdoc/", {data : mydata}, function(data) { alert(data);}, "json");
my alert is never called .... this is a problem because i want to sanitize this data via a django form and the post requests do not seem to making it to the server (in production only).
what am i doing wrong?
UPDATES:
solution: crsf tokens need to be pushed ajax post requests (not gets) as of django 1.3
also, per the link provide below, the following javascript
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$("#csrfmiddlewaretoken").val());
}
}
});
needs to be changed as follows:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$('input[name="csrfmiddlewaretoken"]').val());
}
}
});
the way the csrf token gets rendered in the form must have changed between 1.25 - 1.3??
regardless, it works. thanks for all your help everyone
Can you directly access your javascript files from the production server? Which Django version are you using in production? If you are using 1.2.5+ in production, you will need to push the csrf token to the server during an AJAX post operation.
See the release notes in 1.2.5 and CSRF
To check your Django version:
import django
django.get_version()
Print the above in your production site or from the shell in your production server while making sure you are using the proper Python path.
Your code appears fine with a cursory glance, but I'll show you an example of my ajax form processing code in a hope it'll help with figuring out the error that's occurring. Though, what #dmitry commented should be your first debugging step - use firebug or the inspector to see if the ajax call returns an error.
// js (jQuery 1.5)
$(form).submit(function(event) {
event.preventDefault();
$.post(post_url, $(form).serialize())
.success(function(data, status, jqxhr) {
if (data.success) { // form was valid
$(form)
// other irrelevant code
.siblings('span')
.removeClass('error')
.html('Form Successful');
} else { // form was invalid
$(form).siblings('span').addClass('error').html('Error Occurred');
}
})
.error(function(jqxhr, status, error) { // server error
$(form).siblings('span').addClass('error').html("Error: " + error);
});
});
// django
class AjaxFormView(FormView):
def ajax_response(self, context, success=True):
html = render_to_string(self.template_name, context)
response = simplejson.dumps({'success': success, 'html': html})
return HttpResponse(response, content_type="application/json", mimetype='application/json')
// view deriving from AjaxFormView
def form_valid(self, form):
registration = form.save()
if self.request.is_ajax():
context = {'competition': registration.competition }
return self.ajax_response(context, success=True)
return HttpResponseRedirect(registration.competition.get_absolute_url())
def form_invalid(self, form):
if self.request.is_ajax():
context = { 'errors': 'Error Occurred'}
return self.ajax_response(context, success=False)
return render_to_response(self.template_name, {'errors':form.errors})
Actually, comparing the above to your code, you may need to set the content_type in your django view so that jQuery can understand and process the response. Note that the above is using django 1.3 class-based views, but the logic should be familiar regardless. I use context.success to signal if the form processing passed or failed - since a valid response (json) of any kind will signal the jQuery.post that the request was successful.

Resources