angular6 - I can't get response from Scopus API - httpresponse

I want to use the Scopus API to verify that a DOI exists. I'm using the "Cited By" option. I did a test of this "http://api.elsevier.com/content/search/scopus?query=DOI(10.1016/j.stem.2011.10.002)" link in POSTMAN and it works, but when I did the implementation in Angular this is what returns.
Angular code
let headers = new Headers({
'X-ELS-APIKey': apikey,
'Accept': 'application/json',
});
this._http.get('http://api.elsevier.com/content/search/scopus?query=DOI(' + doi + ')', { headers: headers }).pipe(map(res => res.json())).subscribe(
response => {
console.log("Response");
console.log(response);
},
error => {
console.log("Error");
console.log(error);
}
);
Any help is greatly appreciated :)

Finally I solved it, the problem was that the "doi" string needed to go through the encodeURIComponent() function. I leave the code in case someone needs it.
welcome.component.ts:
let doi = encodeURIComponent('10.1017/j.stem.2011.10.002');
this._scopusService.getPublication(doi).subscribe(
response => {
console.log("DOI exists");
},
error => {
console.log("DOI doesn't exists");
}
scopus.service.ts:
public getPublication(doi) {
let headers = new Headers({
'Accept': 'application/json',
'X-ELS-APIKey': this.apiKey
});
return this._http.get('https://api.elsevier.com/content/search/scopus?query=DOI(' + doi + ')', { headers: headers }).pipe(map(res => res.json()));
}

Related

Cannot upload image to laravel from react-native

I'm trying to let the user upload an image through react-native, but apparently, laravel is not being able to read any value from the request. This is what I'm trying to do with axios:
const data = new FormData()
data.append('subject_id', this.props.navigation.getParam('id'))
data.append('name', this.state.title)
// I don't think the path is enough, it will probably just send the path as a string instead of the image. You need to load the actual file and append that
data.append('image', {
uri: this.state.image,
type: 'image/jpeg',
name: 'image'
});
data.append('progress', this.state.progress * 100)
data.append('description', this.state.description)
data.append('date', this.state.date)
axios.post('https://example.com/api/auth/storeTask', data, {
headers: {
'Authorization': access,
"Content-Type": "multipart/form-data"
},
}).then(result => { })
.catch(err => console.warn)
The image is not found when I try to access the resource.
You should use a FormData object:
const data = new FormData()
data.append('subject_id', this.props.navigation.getParam('id'))
data.append('name', this.state.title)
// I don't think the path is enough, it will probably just send the path as a string instead of the image. You need to load the actual file and append that
data.append('image', this.state.image)
data.append('progress', this.state.progress * 100)
data.append('description', this.state.description)
data.append('date', this.state.date)
axios.post('https://example.com/api/auth/storeTask', data, {
headers: {
'Authorization': access,
"Content-Type": "multipart/form-data"
},
}).then(result => {})
.catch(err => console.warn)
You didn't send complete info like responses and logs, by the way,
Please check this instruction:
make sure your CSRF in verifyCSRFtoken is allowed
use FormData to upload your file
your code coulde be like this:
import axios, { post } from 'axios';
const url = '/uploadPic';
const formData = new FormData();
formData.append("image", {
name: this.state.photo.fileName,
type: this.state.photo.type,
uri: this.state.photo.uri,
});
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
return post(url, formData,config)
for react native:
if you are in production and using react-native bare, you should add
<application
...
android:usesCleartextTraffic="true"
...
to your android file.

Saving blob image in laravel's controller

In my Laravel 5/vuejs 2.6 I upload an image with the vue-upload-component and am sending a requested image blob
I try to save it with the controller code like :
if ( !empty($requestData['avatar_filename']) and !empty($requestData['avatar_blob']) ) {
$dest_image = 'public/' . Customer::getUserAvatarPath($newCustomer->id, $requestData['avatar_filename']);
$requestData['avatar_blob']= str_replace('blob:','',$requestData['avatar_blob']);
Storage::disk('local')->put($dest_image, file_get_contents($requestData['avatar_blob']));
ImageOptimizer::optimize( storage_path().'/app/'.$dest_image, null );
} // if ( !empty($page_content_image) ) {
As result, I have an image uploaded, but it is not readable.
The source file has 5 Kib, the resulting file has 5.8 Kib and in the browser's console I see the blobs path as
avatar_blob: "blob:http://local-hostels2.com/91a18493-36a7-4023-8ced-f5ea4a3c58af"
Have do I convert my blob to save it correctly?
MODIFIED :
a bit more detailed :
In vue file I send request using axios :
let customerRegisterArray =
{
username: this.previewCustomerRegister.username,
email: this.previewCustomerRegister.email,
first_name: this.previewCustomerRegister.first_name,
last_name: this.previewCustomerRegister.last_name,
account_type: this.previewCustomerRegister.account_type,
phone: this.previewCustomerRegister.phone,
website: this.previewCustomerRegister.website,
notes: this.previewCustomerRegister.notes,
avatar_filename: this.previewCustomerRegister.avatarFile.name,
avatar_blob: this.previewCustomerRegister.avatarFile.blob,
};
console.log("customerRegisterArray::")
console.log(customerRegisterArray)
axios({
method: ('post'),
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
}).then((response) => {
this.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
alert( "SAVED!!::"+var_dump() )
}).catch((error) => {
});
and this.previewCustomerRegister.avatarFile.blob has value: "blob:http://local-hostels2.com/91a18493-36a7-4023-8ced-f5ea4a3c58af"
where http://local-hostels2.com is my hosting...
I set this value to preview image defined as :
<img
class="img-preview-wrapper"
:src="previewCustomerRegister.avatarFile.blob"
alt="Your avatar"
v-show="previewCustomerRegister.avatarFile.blob"
width="256"
height="auto"
id="preview_avatar_file"
>
and when previewCustomerRegister.avatarFile.blob is assigned with uploaded file I see it in preview image.
I show control with saving function in first topic but when I tried to opened my generated file with kate, I found that it
has content of my container file resources/views/index.blade.php...
What I did wrong and which is the valid way ?
MODIFIED BLOCK #2 :
I added 'Content-Type' in request
axios({
method: ('post'),
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
headers: {
'Content-Type': 'multipart/form-data'
}
but with it I got validation errors in my control, as I define control action with request:
public function store(CustomerRegisterRequest $request)
{
and in app/Http/Requests/CustomerRegisterRequest.php :
<?php
namespace App\Http\Requests;
use App\Http\Traits\funcsTrait;
use Illuminate\Foundation\Http\FormRequest;
use App\Customer;
class CustomerRegisterRequest extends FormRequest
{
use funcsTrait;
public function authorize()
{
return true;
}
public function rules()
{
$request= Request();
$requestData= $request->all();
$this->debToFile(print_r( $requestData,true),' getCustomerValidationRulesArray $requestData::');
/* My debugging method to write data to text file
and with Content-Type defined above I see that $requestData is always empty
and I got validations errors
*/
// Validations rules
$customerValidationRulesArray= Customer::getCustomerValidationRulesArray( $request->get('id'), ['status'] );
return $customerValidationRulesArray;
}
}
In routes/api.php defined :
Route::post('customer_register_store', 'CustomerRegisterController#store');
In the console of my bhrowser I see : https://imgur.com/a/0vsPIsa, https://imgur.com/a/wJEbBnP
I suppose that something is wrong in axios header ? without 'Content-Type' defined my validation rules work ok...
MODIFIED BLOCK #3
I managed to make fetch of blob with metod like :
var self = this;
fetch(this.previewCustomerRegister.avatarFile.blob) .then(function(response) {
console.log("fetch response::")
console.log( response )
if (response.ok) {
return response.blob().then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
// myImage.src = objectURL;
console.log("objectURL::")
console.log( objectURL )
console.log("self::")
console.log( self )
let customerRegisterArray =
{
username: self.previewCustomerRegister.username,
email: self.previewCustomerRegister.email,
first_name: self.previewCustomerRegister.first_name,
last_name: self.previewCustomerRegister.last_name,
account_type: self.previewCustomerRegister.account_type,
phone: self.previewCustomerRegister.phone,
website: self.previewCustomerRegister.website,
notes: self.previewCustomerRegister.notes,
avatar_filename: self.previewCustomerRegister.avatarFile.name,
avatar: objectURL,
};
console.log("customerRegisterArray::")
console.log(customerRegisterArray)
axios({
method: 'POST',
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
// headers: {
// 'Content-Type': 'multipart/form-data' // multipart/form-data - as we need to upload with image
// }
}).then((response) => {
self.is_page_updating = false
self.message = ''
self.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
alert( "SAVED!!::")
}).catch((error) => {
self.$setLaravelValidationErrorsFromResponse(error.response.data);
self.is_page_updating = false
self.showRunTimeError(error, this);
self.showPopupMessage("Customer Register", 'Error adding customer ! Check Details fields !', 'warn');
// window.grecaptcha.reset()
self.is_recaptcha_verified = false;
self.$refs.customer_register_wizard.changeTab(3,0)
});
});
} else {
return response.json().then(function(jsonError) {
// ...
});
}
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ', error.message);
});
In objectURL and self I see proper values : https://imgur.com/a/4YvhbFz
1) But checking data on server in laravel's control I see the same values I had at start of my attemps to upload image:
[avatar_filename] => patlongred.jpg
[avatar] => blob:http://local-hostels2.com/d9bf4b66-42b9-4990-9325-a72dc8c3a392
Have To manipulate with fetched bnlob in some other way ?
2) If I set :
headers: {
'Content-Type': 'multipart/form-data'
}
I got validation errors that my data were not correctly requested...
?
You're using request type as application/json hence you won't be able to save the image this way, for a file upload a request type should be multipart/form-data in this case you'll need to send request as
let customerRegisterArray = new FormData();
customerRegisterArray.put('username', this.previewCustomerRegister.username);
customerRegisterArray.put('email', this.previewCustomerRegister.email);
....
customerRegisterArray.put('avatar', this.previewCustomerRegister.avatarFile);
console.log("customerRegisterArray::")
console.log(customerRegisterArray)
axios({
method: ('post'),
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then((response) => {
this.showPopupMessage("Customer Register", 'Customer added successfully !Check entered email for activation link !', 'success');
alert( "SAVED!!::"+var_dump() )
}).catch((error) => {});
Thank you for your help!
Valid decision was :
var self = this;
fetch(this.previewCustomerRegister.avatarFile.blob) .then(function(response) {
if (response.ok) {
return response.blob().then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
let data = new FormData()
data.append('username', self.previewCustomerRegister.username)
data.append('email', self.previewCustomerRegister.email)
data.append('first_name', self.previewCustomerRegister.first_name)
data.append('last_name', self.previewCustomerRegister.last_name)
data.append('account_type', self.previewCustomerRegister.account_type)
data.append('phone', self.previewCustomerRegister.phone)
data.append('website', self.previewCustomerRegister.website)
data.append('notes', self.previewCustomerRegister.notes)
data.append('avatar_filename', self.previewCustomerRegister.avatarFile.name)
data.append('avatar', myBlob)
axios({
method: 'POST',
url: window.API_VERSION_LINK + '/customer_register_store',
data: data,
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data' // multipart/form-data - as we need to upload with image
}
}).then((response) => {
self.is_page_updating = false
self.message = ''
self.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
alert( "SAVED!!::123")
// self.$router.push({path: '/'});
}).catch((error) => {
self.$setLaravelValidationErrorsFromResponse(error.response.data);
self.is_page_updating = false
self.showRunTimeError(error, this);
self.showPopupMessage("Customer Register", 'Error adding customer ! Check Details fields !', 'warn');
window.grecaptcha.reset()
self.is_recaptcha_verified = false;
self.$refs.customer_register_wizard.changeTab(3,0)
});
});
} else {
return response.json().then(function(jsonError) {
// ...
});
}
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ', error.message);
});
and common laravel's file uploading functionality :
$customerAvatarUploadedFile = $request->file('avatar');
...

Converting working Ajax call to Angular Observable

I have an existing JavaScript application that submits documents (.pdf, .txt...) to Solr for text extraction. I am now trying to convert that capability to an Angular-6 implementation and am struggling with the whole observable pattern. Below is the working js code, followed by my angular component and service .ts files. I think I'm close, but no cigar.
let myReader = new FileReader();
myReader.onloadend = function() {
fileAsBlob = myReader.result;
sendToSolr(fileAsBlob);
};
fileAsBlob = myReader.readAsArrayBuffer(file);
/* Get the unique Id for the doc and append to the extract url*/
let docId = $("#post_docId").val();
let extractUrl = "http://localhost:8983/solr/" + core + "/update/extract/?commit=true&literal.id=" + docId;
/* Ajax call to Solr/Tika to extract text from pdf and index it */
function sendToSolr(fileAsBlob) {
$.ajax({
url: extractUrl,
type: 'POST',
data: fileAsBlob,
cache: false,
jsonp: 'json.wrf',
processData: false,
contentType: false,
echoParams: "all",
success: function(data, status) {
//console.log("Ajax.post successful, status: " + data.responseHeader.status + "\t status text: " + status);
//console.log("debug");
getDocument(docId);
},
error: function(data, status) {
//console.log("Ajax.post error, status: " + data.status + "\t status text:" + data.statusText);
},
done: function(data, status) {
//console.log("Ajax.post Done");
},
});
}
All the above does is use a fileReader to read a local file into an ArrayBuffer, and submits that ArrayBuffer to Solr via an Ajax call. In my success I do call another function (getDocument) which just queries Solr (By docId) for the document I just submitted and displays it. Not beautiful, but it works.
For the angular version I have the following service:
constructor(private http: HttpClient) { }
postDocToSolr(fileAsBlob: any): Observable<any> {
let httpHeaders = new HttpHeaders()
.set('type' , 'POST')
.set('jsonp', 'json.wrf')
.set('processData', 'false')
.set('echoParams', 'all')
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('charset', 'utf-8')
.set('data', fileAsBlob);
let options = {
headers: httpHeaders
};
return this.http.post(this.extractUrl, fileAsBlob, options);
}
}
I tried posting the entire service, but it threw the formatting off so here is the POST part of the service.
And in my component I call the service:
extractText(fileContents: any) {
console.log("In the Document.extractText() method");
//this.processDocument(fileContents);
this.textExtractor.postDocToSolr(fileContents)
.subscribe(data => {
console.log("Debug");
console.log("Data: ") + data;
},
error => {
console.log("Error" + error);
}
);
console.log("Debug");
}
Note I've done the fileReader already and am submitting basically the same ArrayBuffer.
The only hint is the in the error => log the error callback(Right term?)on the observable. I get an error code 400, bad request with the message:
"msg":"URLDecoder: Invalid digit (P) in escape (%) pattern"
Which doen't help me much. I'm wondering if it's an encoding issue (UTF-8) but not sure where to begin. Would appreciate a nudge in the right direction.
It looks like the problem is how angular is encoding your URI, I would open your network tool of choice (network tab, fiddler, etc) and look at the sent request URI of each. I suspect they'll be different.
Well, it's often the small things that trip me up. I needed to set the Content-Type to "false" and everything works fine. I also re-did the creation of the httpHeaders, but I think either way would have worked. The working postToSolr Service method is:
export class TextExtractorServiceService {
extractUrl: string = "http://localhost:8983/solr/tater/update/extract/?commit=true&literal.id=778";
constructor(private http: HttpClient) { }
postDocToSolr(fileAsBlob: any): Observable<any> {
const httpOptions = {
headers: new HttpHeaders({
"jsonp": "json.wrf",
"processData": "false",
"echoParams" : "all",
"Content-Type": "false",
"cache": "false"
})
};
return this.http.post(this.extractUrl, fileAsBlob, httpOptions);
}
}
Thanks to all who took a look.

How to pass the Query Data in Body for making REST API call in graphql

I am doing a post operation where i am getting some response.
My URl looks Like:
http://domainname/api/v1:id
As a part of body i want to pass the below data:
{ elemetnt { id, name } }
Can anybody suggest me how i can achieve this.
i am trying with the below code but i am getting 404:
let queryParam = `{ elemetnt { id, name } }`;
this.http.post(`http://domainname/api/v1:1`, {
query: queryParam,
}, {
headers: new Headers({
'Content-Type': 'application/graphql',
}),
})
.catch((error: Response | any) => {
console.log(error);
return Observable.of(error);
})
.subscribe((res) => {
console.log(JSON.stringify(res));
});
I know i am doing something wrong. But, if somebody can help me on this then it would be great help.
It depends on method which receiving this data, but this is correct format for you as given in question
queryParam= { element : { id: "0000" , name: "name" };
you may need to stringy your solution
Canyou please try with
'Content-Type': 'application/json'
and pass json body like
{"query":"{ elemetnt { id, name } }" }
I think this may help you

How to dynamically change the network layer in Relay

I know relay can inject a network layer when bootstrapping like below:
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://example.com/graphql', {
headers: {
Authorization: 'Basic SSdsbCBmaW5kIHNvbWV0aGluZyB0byBwdXQgaGVyZQ==',
},
})
);
But how about if I need to tell what the header is later(like after signing in)?
I found a simple trick. You can pass in headers object and update its pointer value.
const headers = {
Authorization: '',
};
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://example.com/graphql', {
headers: headers,
})
);
// To update the authorization, set the field.
headers.Authorization = 'Basic SSdsbCBmaW5kIHNvbWV0aGluZyB0byBwdXQgaGVyZQ=='
Great question. I imagine you're setting the network layer in your base component file. You could create a function wrapping the Relay.injectNetworkLayer call that updates the Auth header when you need to.
When loading the app, you could do something like this:
export function setNetworkLayer() {
return new Promise((resolve, reject) => {
var options = {};
if (localStorage.authToken) {
options.headers = {
Authorization: 'Basic ' + localStorage.authToken
}
}
else {
options.headers = {};
}
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://example.com/graphql', options)
);
resolve(options);
});
})
}
And if you wanted to update the network layer, you'd do something like this:
loginUser().then((res) => {
localStorage.authToken = res.token;
setNetworkLayer();
return;
})
I asked the question in github relay repo, they recommend me to use this react-relay-network-layer library to solve the problem. I believe it will be the best option to solve the problem.

Resources