I am trying to use the Mendeley API to download a file attached to a resource (document). I am following the developer documentation here:
https://dev.mendeley.com/methods/#downloading-a-file
It looks like it should be fairly straight forward. I have the Oauth flow figured out and I am able to pull all of my documents from Mendeley library. I am also able to get the attached file id for a given document.
It is when I try to use that ID to retrieve the file (a pdf in this case) that it fails. I have copied the parameters to postman and it works fine there. But when I try to do it in my Ruby-on-rails app using javascript it fails.
I am a novice when it comes to javascript so I may very well be missing something obvious.
Here is the javascript code snippet:
downloadFile = (json) => {
this.getAuthCode();
this.provideToken = (token) => {
const access_token = token;
var myHeaders = new Headers();
myHeaders.append("Authorization", `Bearer ${access_token}`);
var requestOptions = {
method: 'GET',
headers: myHeaders,
};
fetch(`https://api.mendeley.com/files/${json[0].id}`, requestOptions).then(resp => {
console.log(resp)
})
}
}
The json argument is an array of files associated with a document. It seems to work ok until the Mendeley server redirects to the AWS S3 storage URL for the file in question. Here is the Chrome developer console output:
`Response {type: "cors", url: "https://mendeley-files.s3.amazonaws.com/31/9f/319f…09d6b8443d1e734fad70c551e37a0a3497b42c69fd0796c91", redirected: true, status: 400, ok: false, …}
body: (...)
bodyUsed: false
headers: Headers
__proto__: Headers
ok: false
redirected: true
status: 400
statusText: "Bad Request"
type: "cors"
url: "https://mendeley-files.s3.amazonaws.com/31/9f/319fe16b678cc65092ef5aa732b3e4c137f272f3?response-content-disposition=attachment%3Bfilename%3D%222003-Psychometric_properties_of_student_ratings_of_instruction_in_online_and_on-campus_courses.pdf%22&response-content-type=application%2Fpdf&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEOz%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCWV1LXdlc3QtMSJIMEYCIQCP0qEL1EJeGKIBVmxX2FaPIZftcmqiW%2FzgDY5ysRs25AIhAMM6q3YzWSubSnuuXOs9gi8voOZ%2BRrkQS343IkihJka1KvYDCDUQAhoMMTA4MTY2MTk0NTA1Igx2zsOuUuv1h6V8cw0q0wMNdVy5izfbA30MysjiNXG3V%2F21aHfn2xXF8ZKq74%2FAbDUbTzKfFWuN79ARNbEyeGinrXdlRXb%2FlEP9ZRgb6xh1%2BtCBtpqT8esZmdZcERC%2Fpup8dtd8q%2BWeCxVKVIyYZffZJvJW1wQOONhMJnfpb751Lr1pTN%2BAu38q8Dky8sOB%2B%2FyH0xOXbP5S0IFErM0B1Ac7eJLOTLrrzwuQ17Z1ZF%2FN5ZenKtV5rrIRR8RU0%2FnzY6EQip1LIHy7l%2F0rN9srGyM1n3fT5trqKL7H6mi79ZlbN0RJ%2FZAtO6pWTL6DbpFzrlCTt6fI%2B2UqdEDrVBO4QT8ROYnd8dYd%2F3hrB1%2BOjuugRDRE6tUehgn9lnFWUndww0XHOWUq8GWAOImeBts7fazUmcCv8lzhH09FYwbcaOKghr6HhJko5UUpeGV4TjMVCA1wUZ4G3DBBVTUIKBLbve0oWFexVFj2J380neGXywdPbEzUcp5o6N%2FEGOW5nMJHlwIquMDubiwgrQ5ANES6RhuO%2BBQTHuy9JdL2KrfhEHA3UJBm6T4Azg1XgEIpXo84Hs7cc2x7ewZ6CPUyzXcc%2Bx72u1o6RwoE12AKdp%2BwqZK4NnFmn6jXKKCSShgmVuqUr3ARVTDmy%2Bb1BTruAQmSrzEXqXzi5Ut4AWjWCEMvw4mB5Yk8W6v5V6YTRtwp8ebqI9Q4hzfMT62ko1AQsBwhKX8anZTIvDVpImcjbUQnaWVGKehj0OGVOb%2FnCn3JXZRq2bCKfQ2Mf7YxlWSHIy9CWqZiW4uTpdSfk5kOOnYQhrKhHQJc%2BM%2F7BldOy72AVgikcmvQdR3k315KNwh%2BJ96ci4LvRa%2BiXw5stATLCQCSKWPYCRonCighfGxNoAyWvvuTkjaQe3bm6X64Giwm2qyyAso05hnC3gotbefpEFNjx2%2Brgm2G%2FzNwdKkr2I%2BFy%2BnGXVNNG2ruh2DMVOw%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200511T205618Z&X-Amz-SignedHeaders=host&X-Amz-Expires=600&X-Amz-Credential=ASIARSLZVEVE5V2CTSJF%2F20200511%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=96b2a6673ab742909d6b8443d1e734fad70c551e37a0a3497b42c69fd0796c91"
__proto__: Response
arrayBuffer: ƒ arrayBuffer()
blob: ƒ blob()
body: (...)
bodyUsed: (...)
clone: ƒ clone()
formData: ƒ formData()
headers: (...)
json: ƒ json()
ok: (...)
redirected: (...)
status: (...)
statusText: (...)
text: ƒ text()
type: (...)
url: (...)
constructor: ƒ Response()
Symbol(Symbol.toStringTag): "Response"
get body: ƒ body()
get bodyUsed: ƒ bodyUsed()
get headers: ƒ headers()
get ok: ƒ ok()
get redirected: ƒ redirected()
get status: ƒ status()
get statusText: ƒ statusText()
get type: ƒ type()
get url: ƒ url()
__proto__: Object`
It clearly finds the correct file but fails to download it. When I run it in postman it downloads the file.
I have tried adding various headers that show up in Postman as 'hidden' but I get basically the same response. Any thoughts or direction on this would be greatly appreciated.
Stay safe!
Reference documentation: https://dev.mendeley.com/code/core_quick_start_guides.html#file_download
This is working for me:
async function getFile(fileId) {
const url = `https://api.mendeley.com/files/${fileId}`;
const res = await superagent.get(url).auth(accessToken, { type: 'bearer' });
const [fileUrl] = res.redirects;
return fileUrl;
}
Related
this is the API call
export const socialPostUpdateBio = (publicKey,sig,about)=>{
let data=
"pub="+ publicKey+
"&sig="+ sig.sig+
"&about="+about
console.log('====',data)
fetch('https://endpoint/postUpdateBio', {
method: 'POST',
headers: new Headers({
"Content-Type": "application/x-www-form-urlencoded", // <-- Specifying the Content-Type
Accept: "application/json"
}),
body:data
}).then((response) => response.json())
.then((responseJson) => {
console.log("New post updateBio",responseJson);
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
}
this is data about:Its coming as a string not as a object
{name:"Guruprakash Gupta",dob:"14/08/1997",location:"Bangalore",bio:"Gratitude",sex:"Male",profile_pic:"QmdDjpQ3G6vg7zkU2BBPMQJYsnnRtTEDEtL9xBXjvPh4i4-image-jpg"}
before api call we have a one more function where we are signing the data with private key,so signing of data is correct here so i haven't inculded that function.
this is what response im getting
Response {type: "default", status: 524, ok: false, statusText: undefined, headers: Headers, …}type: "default"status: 524ok: falsestatusText: undefinedheaders: Headers {map: {…}}url: "https://murmurjapi.wandx.co/accounts/postUpdateBio"_bodyInit: Blobdata: (...)size: (...)type: (...)_data: {size: 4831, offset: 0, blobId: "d07d8515-51de-48c1-950d-7d9a77c8c640"}size: 4831offset: 0blobId: "d07d8515-51de-48c1-950d-7d9a77c8c640"__proto__: Object__proto__: Objectdata: (...)size: (...)type: (...)constructor: ƒ Blob()slice: ƒ slice(start, end)close: ƒ close()get data: ƒ ()set data: ƒ (data)get size: ƒ ()get type: ƒ ()__proto__: Object_bodyBlob: Blob {_data: {…}}__proto__: ObjectbodyUsed: false_initBody: ƒ (body)blob: ƒ ()arrayBuffer: ƒ ()text: ƒ ()formData: ƒ ()json: ƒ ()clone: ƒ ()constructor: ƒ Response(bodyInit, options)__proto__: Object
You're receiving HTML (or XML) back from the server, but response.json() telling XML or HTML to parse as JSON. Parser cannot parse XML or HTML, so it's showing this error. Check the "Network" tab in Chrome dev tools or postman client to see contents of the server's response.
Here's what I did on the react end:
componentDidMount(){
console.log('zzzzzzzzzzz')
fetch('http://localhost:5000/z', {mode: 'no-cors'}).then(res=>{console.log(res)
this.setState(res)})
}
Here's what I did with NodeJS + Express:
app.get('/z', (req, res)=>{
console.log('requested')
res.send({msg: "YEEEEHAW"})
})
The request does go through, but it's not what I wanted (the 'YEEEEHAW' is nowhere to be found in browser console):
Response {type: "opaque", url: "", redirected: false, status: 0, ok: false, …}
type: "opaque"
url: ""
redirected: false
status: 0
ok: false
statusText: ""
headers: Headers
__proto__: Headers
body: (...)
bodyUsed: false
__proto__: Response
type: (...)
url: (...)
redirected: (...)
status: (...)
ok: (...)
statusText: (...)
.......
What did I do wrong here? How can I fix it? (To be clear, I did look through + expand every expandable field in the logged object so I'm pretty sure I didn't miss it)
To read response content, you can use res.json():
componentDidMount(){
console.log('zzzzzzzzzzz')
fetch('http://localhost:5000/z', {mode: 'no-cors'})
.then(res=>res.json())
.then(res=>{
console.log(res)
this.setState(res)
})
}
For return a json replace
res.send({msg: "YEEEEHAW"})
for
res.json({msg: "YEEEEHAW"})
I would like to a check for max-age so I remove items from cache when they get old, but I can't get my own header back for some reason.
export function cacheResponse(url, response) {
caches.open('my-cache').then(function(cache) {
cache.put(url, new Response(JSON.stringify(response), {
headers: {
'Cache-Control': 'max-age=1',
'Content-Type': 'application/json;charset=UTF-8'
}
}));
});
}
cacheResponse('/hello', {hello: "world"})
I can see this working in the Application tab in chrome and I can see those 2 headers in the preview, but when I pull the item back out the headers object is null.
cache.match(url).then(async function(object) {
console.log(object.headers) // null
var body = await object.clone().json(); // {hello: "world"}
})
The object looks like this
object: Response
body: ReadableStream
bodyUsed: false
headers: Headers
__proto__: Headers
ok: true
redirected: false
status: 200
statusText: ""
type: "default"
url: ""
Seems like I should be able to lookup the headers from calling match() no?
That should work; you should be able to call response.headers.get('cache-control') to retrieve the value (assuming this is a same-origin response).
Here's a snippet of code that I just tested which worked when run in the JS console:
async function test() {
const constructedResponse = new Response('test', {
headers: {'cache-control': 'max-age=1'}
});
const cache = await caches.open('test');
cache.put('/test', constructedResponse);
const matchedResponse = await cache.match('/test');
console.log(`cache-control: ${matchedResponse.headers.get('cache-control')}`);
}
I am totally new to javascript . I just want to show a notification using notify.js when a button is clicked.
Following is my RestController code:
#RequestMapping(value = "/checkCurrentBranch" , method=RequestMethod.GET)
public String checkCurrectGitBranch(Model model, HttpServletResponse response) {
String branchName = "";
GitInfo gitInfo = new GitInfo();
JsonFactory factory = new JsonFactory();
String json = apiService.readGitProperties();
ObjectMapper mapper = new ObjectMapper(factory);
JsonNode rootNode;
try {
rootNode = mapper.readTree(json);
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
if (field.getKey().toString().equalsIgnoreCase("git.branch")) {
branchName = field.getValue().toString();
adminAppLogger.info("Current Branch name :: "+branchName);
}
}
} catch (IOException e) {
adminAppLogger.error("Error while getting current Git branch :" + e);
branchName = "Error while fetching branch name";
}
model.addAttribute("res", branchName);
return branchName;
}
Following is my js code:
$('#gitBranch').click(function(res) {
/* <![CDATA[ */
var path = /* [[#{/}]] */'checkCurrentBranch';
/* ]]> */
$.notify(res, "info");
console.log(res);
});
I think I am missing some points but I am stuck. Any suggestions?
I tried using axios following is my js:
$('#gitBranch').click(function(res) {
/* <![CDATA[ */
var path = /* [[#{/}]] */'checkCurrentBranch';
/* ]]> */
axios({
method:'get',
url:path,
responseType:'json'
})
.then(function (response) {
console.log(response)
$.notify(data,"info")
});
});
Following response I get on brwoser console. Now I just want that data field to be shown as notification :
{data: "qc_mediaworker_details", status: 200, statusText: "", headers: {…}, config: {…}, …}
config
:
{adapter: ƒ, transformRequest: {…}, transformResponse: {…}, timeout: 0, xsrfCookieName: "XSRF-TOKEN", …}
data
:
"qc_mediaworker_details"
headers
:
{pragma: "no-cache", date: "Sun, 04 Nov 2018 05:59:32 GMT", x-content-type-options: "nosniff", x-frame-options: "DENY", content-type: "application/json;charset=UTF-8", …}
request
:
XMLHttpRequest {onreadystatechange: ƒ, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status
:
200
statusText
:
""
__proto__
:
Object
You need to properly use data key in axios response block.
axios({
method:'get',
url:path,
responseType:'json'
})
.then(function (response) {
console.log(response)
$.notify(response.data,"info")
});
In above code, I replaced data by response.data
, because according your give code, data is not declared, that means its undefined. So if you mean data to that data which you get in axios response, then you need to access data by $.notify(response.data,"info") instead of $.notify(data,"info")
You don't have anywhere http request.
I recommend you using axios (because it's simple)
Sample code:
axios.get('host:port/checkCurrentBranch')
.then(response => {
// do what you want to do
})
.catch(error => {
// do something if an error occurs
})
I have a simple fetch request like this:
fetch('/data', {method: 'POST', credentials: 'same-origin', body: {'name': 'alice'}}).then(function(response){
console.log('reply:');
console.log(response);
});
Basically it should send a POST request to the local address /data with some parameters in it (same thing as an HTML form does) and then return the reply it gets (the /data page simply prints out "this is a test response")
But when I look at the console.log(response); it looks like this:
Response { type: "basic", url: ".../data", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers, bodyUsed: false }
The actual string returned by the page /data ("this is a test response") is nowhere to be found.
So how can I retrieve the actual returned string then?
To read the body of the response, you need to actually do that. See the details on MDN (here, here, and here), but in brief, if you want the body as text, then:
fetch(/*...*/)
.then(function(response) {
return response.text();
})
.then(function(responseText) {
// ...
});