backbone destroy not sending params - ruby-on-rails-3

I've got a backbone model that I'm trying to destroy, but no params are being sent with the request, so the server is returning a 'Delete 404 not found' error.
I'll admit my structure is a bit strange as I'm creating/destroying the items based on if they are in a list already or not.
var list_item = new MyApp.Models.ListItem({item_id: this.model.id, group_id: this.model.group_id});
if($(e.currentTarget).hasClass('add')){
list_item.save(list_item, {
success: function(response){
this.model.attributes.addedtolist_id = response.id
console.log(this.model);
},
error: function(){
alert('could not save item');
}
});
} else if($(e.currentTarget).hasClass('remove')) {
list_item.id=this.model.addedtolist_id;
list_item.attributes.id = this.model.addedtolist_id;
console.log(list_item);
list_item.destroy({
success: function(){
alert('delete');
},
error: function(){
alert('could not uncheck');
}
});
}
the console output for list_item before destroy is
_escapedAttributes: Object
_previousAttributes: Object
_setting: false
attributes: Object
id: 2
item_id: 66
group_id: 64
__proto__: Object
cid: "c23"
id: 2
__proto__: q
but when I look at the headers sent with the delete request, I don't have any params being sent.
-----------------------update params being sent, 404 still being returned --------------
as per Yaroslav's recommendation, I've added a 'header' to the destroy method, but my rails controller is still returning a DELETE 404 not found error. I'm just trying to return the listitem to make sure i'm getting the right one before I destroy it.
My controller is
def destroy
listitem = Listitem.find(params[:id])
return render :json => listitem
end

I'd guess that you're setting the url in the model to a string:
Backbone.Model.extend({
url: '/list_items',
//...
});
That will tell Backbone to use exactly /list_items as the URL for all actions. You should use a function:
url: function() { return '/list_items/' + encodeURIComponent(this.id) }
or use a string with urlRoot and let the default url function add the id:
urlRoot: '/list_items'

What params are you expecting to be sent? Destroy makes just a http delete request by the url without body or any additional headers by default. The params argument is pased to the jquery ajax function, so you can specify headers there:
model.destroy({
...
headers : {
your_header : 123
}
})

list_item.destroy( **l** {
success: function(){
alert('delete');
}, ... );
Is that extra number one the problem?

Related

How to show input and output exemple with nelmio-api-bundle and php8.1

I'm currently trying to make an API doc page thanks to nelmio-api-bundle. I only have one route which is a POST route. I'm receiving a JSON in the body of the request and I'm using the Serializer from symfony to deserialize it in a DTO. I'm also using a DTO for the response (which contains the status code, a bool set to true or false, and a message). Now I'm trying to use these DTO (for input and output) to build the API documentation with nelmio-api-bundle but how to make it ? I'm using PHP8.1 attributes to make it, for response it almost works (except that the response is shows as an array) but I don't know how to make it for the inputs.
Here is my current code:
#[Route('/user', methods: ['POST'])]
#[OA\Parameter(
name: 'user',
description: 'The user information in JSON',
in: 'query',
required: true
)]
#[OA\Response(
response: 200,
description: 'Returns the success response',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: SuccessResponseDTO::class))
)
)]
public function registerUser(Request $request, LoggerInterface $logger): JsonResponse
{
//the code to register the user
}
And here is the result:
Do someone know how to make it ?

Angular6 - value of response header from one http request to another one as option without nested subscribes

I need to retrieve all specified records from an api endpoint using http get request. The information what is the of total records available is in the X-Total response header.
I tried to retrieve the value of X-Total response header with one http request and then passing the value to another http get request as the value of X-Size header - this approach resulted in nested subscribe:
getTotalRecords () {
return this.http.get('http://localhost:4200/api/loans/marketplace?', {
headers: new HttpHeaders({
'X-Size': '1'
}),
params: new HttpParams().set('rating__eq', 'A').set('fields', 'rating,amount'),
observe: 'response'
})
};
getData() {
this.getTotalRecords().subscribe(data => {
this.http.get('http://localhost:4200/api/loans/marketplace?', {
headers: new HttpHeaders({
'X-Size': data.headers.get('X-Total')
}),
params: new HttpParams().set('rating__eq', 'A').set('fields', 'rating,amount'),
observe: 'response'
}).subscribe(data => {
console.log(data.body);
})
})
};
This works but it seems to me like there has to be a better way of doing this. Also I have this code directly in a component because I wasn't able to make a service out of it - I don't know how to return an observable if I have to subscribe to one to create the other.
Thank you
You can use concatMap to invoke the inner Observable and then share before returning the Observable to make sure you won't make multiple HTTP calls when making multiple subscriptions:
getData() {
return this.getTotalRecords().pipe(
concatMap(data => this.http.get(...)),
share(),
);
}

Axios - Remove headers Authorization in 1 call only

How can I remove the axios.defaults.headers.common.Authorization only in 1 call?
I'm setting the default for all the calls to my domain but I have 1 call that I make on another domain and if the token is passed the call gives me an error, when there's no default Auth token saved everything works fine.
So what I'm trying to do is not pass the Auth in that specific call
I tried this but it doesn't work
loadApiCoins({ commit }) {
Vue.axios({
method: 'get',
url: 'https://api.coinmarketcap.com/v1/ticker/',
headers: {
'Authorization': '',
},
}).then(...)
},
I also tried auth: {...} but that doesn't work either.
What's the solution?
Thanks
Try the following
delete axios.defaults.headers.common["Authorization"];
// or which ever header you have to remove
To send a request without:
Modifying global axios defaults
Creating a new axios instance
Change your request similarly to this:
axios.get('http://example.com', {transformRequest: (data, headers) => {
delete headers.common['Authorization'];
return data;
}
});
The answer I was looking for was posted in the comments of Apurva jain's answer, but hasn't been made an individual answer, so I've posted it separately for easy reference :)
if you already have a default 'Authorization' for all requests
you can create an instance for that specific request
var instance = axios.create();
delete instance.defaults.headers.common['Authorization'];
instance.get("http://api.com");
delete axios.defaults.headers.common["Authorization"];
will solve the problem. But remember to add the authorization header back.
I got the same issue trying to query S3 with my web-service auth token. Fixed it with this.
axios.get("http://api.com", {
headers:{ Authorization:""}
});
You can change the default headers to an empty string, this won't affect the common default headers. Though not entirely sure if all web services will ignore the empty string header.
A simple solution is to remove all common header from a new axios instance:
const awsAxios = axios.create({
transformRequest: (data, headers) => {
// Remove all shared headers
delete headers.common;
// or just the auth header
delete headers.common.Authorization;
}
});
delete request.defaults.headers.common.Authorization
That request should be return of a $axios.create()
To extend on #phantomraa's answer, you might want to use
this.$axios.$get(
url, {
// modify auth header for current request only
transformRequest: (data, headers) => {
// prevent the header from being added by default
delete headers.common['Authorization'];
// some libraries might set it directly as well, e.g. nuxtjs/auth
delete headers['Authorization'];
return data;
}
})
Sorry, need a bit more rep to just comment.
According to the latest axios Request Config documentation we can use transformRequest:
// This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'
// The last function in the array must return a string or an instance of Buffer, ArrayBuffer,
// FormData or Stream
// You may modify the headers object.
An example:
axiosInstance.post('/api/auth-token', { email, password }, {
transformRequest: [
(data, headers) => {
delete headers.common['Authorization'];
return JSON.stringify(data);
},
],
});
Please note the call to JSON.stringify as mentioned in the documentation, you need to return a Buffer, ArrayBuffer, FormData or Stream.
const mynewinstance = axios.create();
mynewinstance.defaults.headers.common = {};
const output = await mynewinstance.get(`https://google.com`);
delete axios.defaults.headers.common["language"];

Getting list with deep=true in Backand

I am having an issue getting relations backing using the deep parameter.
I'm using this url and am expecting it to return my related objects but is not.
url: Backand.getApiUrl() +"/1/objects/blogs?deep=true",
Yes, the deep works only for specific item because of performance reasons.
You should do /1/objects/blogs/1?deep=true
In general we suggest to query the blogs and from the client using promise to get the deep of each one.
If you must get it all at once, you can create server side on demand action, make the query and loop on the results while populating it with the deep. Because it runs on the server side it will be fast. here is a code example for the server-side action:
function backandCallback(userInput,dbRow,parameters,userProfile){
var response=$http({
method: "GET",
url: CONSTS.apiUrl+"/1/objects/blogs",
headers: {
"Authorization": userProfile.token
}
});
var mapping=response.data.map(function(item){
var object=item;
var user=$http({
method: "GET",
url: CONSTS.apiUrl+"/1/objects/users/"+item.author,
headers: {
"Authorization": userProfile.token
}
});
object.author_obj=user;
return object;
})
return mapping;
}

Sencha touch 2 - show response (JSON string) on proxy loading

Is there a way to output the json-string read by my store in sencha touch 2?
My store is not reading the records so I'm trying to see where went wrong.
My store is defined as follows:
Ext.define("NotesApp.store.Online", {
extend: "Ext.data.Store",
config: {
model: 'NotesApp.model.Note',
storeId: 'Online',
proxy: {
type: 'jsonp',
url: 'http://xxxxxx.com/qa.php',
reader: {
type: 'json',
rootProperty: 'results'
}
},
autoLoad: false,
listeners: {
load: function() {
console.log("updating");
// Clear proxy from offline store
Ext.getStore('Notes').getProxy().clear();
console.log("updating1");
// Loop through records and fill the offline store
this.each(function(record) {
console.log("updating2");
Ext.getStore('Notes').add(record.data);
});
// Sync the offline store
Ext.getStore('Notes').sync();
console.log("updating3");
// Remove data from online store
this.removeAll();
console.log("updated");
}
},
fields: [
{
name: 'id'
},
{
name: 'dateCreated'
},
{
name: 'question'
},
{
name: 'answer'
},
{
name: 'type'
},
{
name: 'author'
}
]
}
});
you may get all the data returned by the server through the proxy, like this:
store.getProxy().getReader().rawData
You can get all the data (javascript objects) returned by the server through the proxy as lasaro suggests:
store.getProxy().getReader().rawData
To get the JSON string of the raw data (the reader should be a JSON reader) you can do:
Ext.encode(store.getProxy().getReader().rawData)
//or if you don't like 'shorthands':
Ext.JSON.encode(store.getProxy().getReader().rawData)
You can also get it by handling the store load event:
// add this in the store config
listeners: {
load: function(store, records, successful, operation, eOpts) {
operation.getResponse().responseText
}
}
As far as I know, there's no way to explicitly observe your response results if you are using a configured proxy (It's obviously easy if you manually send a Ext.Ajax.request or Ext.JsonP.request).
However, you can still watch your results from your browser's developer tools.
For Google Chrome:
When you start your application and assume that your request is completed. Switch to Network tab. The hightlighted link on the left-side panel is the API url from which I fetched data. And on the right panel, choose Response. The response result will appear there. If you have nothing, it's likely that you've triggered a bad request.
Hope this helps.
Your response json should be in following format in Ajax request
{results:[{"id":"1", "name":"note 1"},{"id":"2", "name":"note 2"},{"id":"3", "name":"note 3"}]}
id and name are properties of your model NOte.
For jsonp,
in your server side, get value from 'callback'. that value contains a name of callback method. Then concat that method name to your result string and write the response.
Then the json string should be in following format
callbackmethod({results:[{"id":"1", "name":"note 1"},{"id":"2", "name":"note 2"},{"id":"3", "name":"note 3"}]});