URL of a collection in Backbone for RESTful interaction - javascript

Here is a collection I define in backbone.js
var List=Backbone.Collection.extend({
model: Item,
url: "TodoApp/index.php/todo"
});
var list=new List
Then I created a Model in the collection with an ID=80
Now, when I do list.fetch();
It will make a call to
"TodoApp/index.php/todo/80"
However, at the backend, using Codeigniter, I really need to have
TodoApp/index.php/todo/get/82.........where get is a function I defined to access DB
So, should I change the Collection url to "TodoApp/index.php/todo/get"
But again, that's not really where the resource is located?

In route.php try:
$route['todo/(:num)'] = "todo/get/$1";

HERE is what I ended up doing.
I renamed the index of the controller to resource
therefore using a URL of:
TodoApp/index.php/todo/resource
When getting a GET request at
TodoApp/index.php/todo/resource/80
extract the second segment of the URI and read from DB with that.

Related

Laravel resource route delete from axios

I would like to setup axios to delete a record using a resource route:
axios.delete('/job-management', this.deletedata).then((res)=>{
console.log(res);
})
For my routes I have:
Route::resource('job-management', "PositionsController", [ 'as' => 'jobs']);
Now, in my PositionsController I have:
public function destroy(Positions $positions) {
return $positions;
}
But the above always returns "method not allowed". How can I handle a delete request with the axios delete() method?
Laravel throws the MethodNotAllowedHttpException when we attempt to send a request to a route using an HTTP verb that the route doesn't support. In the case of this question, we see this error because the JavaScript code sends a DELETE request to a URL with the path of /job‑management, which is handled by a route that only supports GET and POST requests. We need to change the URL to the conventional format Laravel expects for resourceful controllers.
The error is confusing because it hides the fact that we're sending the request to the wrong URL. To understand why, let's take a look at the routes created by Route::resource() (from the documentation):
Verb URI Action Route Name
GET /job-management index job-management.index
GET /job-management/create create job-management.create
POST /job-management store job-management.store
GET /job-management/{position} show job-management.show
GET /job-management/{position}/edit edit job-management.edit
PUT/PATCH /job-management/{position} update job-management.update
DELETE /job-management/{position} destroy job-management.destroy
As shown above, URLs with a path component of /job-management are passed to the controller's index() and store() methods which don't handle DELETE requests. This is why we see the exception.
To perform a DELETE request as shown in the question, we need to send the request to a URL with a path like /job-management/{position}, where {position} is the ID of the position model we want to delete. The JavaScript code might look something like:
axios.delete('/job-management/5', this.deletedata).then((res) => { ... })
I've hardcoded the position ID into the URL to clearly illustrate the concept. However, we likely want to use a variable for the this ID:
let positionId = // get the position ID somehow
axios.delete(`/job-management/${positionId}`, this.deletedata).then((res) => { ... })
The URL in this form enables Laravel to route the DELETE request to the controller's destroy() method. The example above uses ES6 template string literals because the code in the question suggests that we're using a version of JavaScript that supports this feature. Note the placement of backticks (`) around the template string instead of standard quotation marks.
as I can see in your code above, you pass Positionseloquent as a parameter to destroy method but in your vueJS you don't pass this object. for that you would pass it like this :
axios.delete('/job-management/${id}').then((res)=>{
console.log(res);
})
and the id param inside the url of ur axios delete, it can object of data or any think.
i hope this help you

How to send a resource collection using Restangular?

Let's say I want to send a DELETE request to a resource like /products and I want to delete multiple products.
The whole request would be to the following URI: /products/ids=1&ids=2&ids=3
How can I issue a request like the above one using Restangular?
For now, the issue is that customDELETE receives query string params using an object. Hence, it can't define the same parameter more than once...
Finally it was an easy one:
products.one().customDELETE(null, { ids: [1,2,3,5] } });

modify resource using restangular by making put on name not id

I have profile resource which has
profileName,
firstName ,
Lastname and
id
here profileName is unique and used as resource identifier and id is just a count.
To modify resource it accept put request on
http://localhost:9090/messanger/api/[profileName]
Now problem is whenever I'm making put request, it replace profile name with id. I am unable to make restangular put request on profileName.
Code is as follows.
$scope.editUser=function(id){
var profile=$scope.profiles[id];
$scope.profile=profile;
profile.save().then(function(res){
console.log(res);
});
}
It turn out that there was a problem with method which was handling put request at backend. Object I was passing has 4 properties in java code but when I was passing it from front end I was passing only 3. Previously I was trying
var items=Restanular.all("profiles").getList();
var item=items[i];
item.propertyName=New Value;
item.save();
This should have ideally work but I think it require some thing more as when I called save method it made a request on http://localhost:9090/messanger/api/
rather than making request on http://localhost:9090/messanger/api/[profileName]

How to force a POST request when saving a model?

I need to make a POST to a server-side API. I must send an id key into the request body to the server.
I use a Backbone model. But when I do:
myModel.set("id", somevalue)
myModel.save()
The network request that is fired is : URL/someValue [PUT]
Backbones doesn't do a POST but a PUT and appends the id to the url.
So I just want to pass an id key to the server without Backbone noticing.
From Backbone's doc:
Backbone is pre-configured to sync with a RESTful API.
[...]
The default sync handler maps CRUD to REST like so:
create → POST /collection
read → GET /collection[/id]
update → PUT /collection/id
patch → PATCH /collection/id
delete → DELETE /collection/id
A new entry doesn't have an ID, so if you give an ID to the model before saving it, Backbone defaults to a PUT request because it thinks you want to save an existing entry.
How to make a POST request with an id?
Choose one of the following solutions.
Stick to a RESTful API
This one is the obvious one. If you can, stick to the standard.
Change the API to handle PUT/PATCH requests and only use POST on creation. Make the API endpoint take the ID from the URL.
RESTful API best practices
Pass the type option1
Simple and works really well for a one-off situation.
Every options passed to save (or fetch) overrides the options the sync function defines by default and passes to jQuery.ajax function.
Backbone sync source
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
var url = model.url(); // get the url before setting the `id`
model.save({
id: somevalue
}, {
url: url, // fix the url
type: 'POST' // choose the HTTP verb
});
Fixing the url that the model uses is simple, you have also some choices:
pass the url option (like above)
override the url function of the model
Overriding the url function (source) works well for situation where every call should use a specific url, without the default id appended to it.
var MyModel = Backbone.Model.extend({
url: function() {
return _.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
}
});
Set the idAttribute on the model
This depends on what the id you're trying to pass means in the data.
Backbone Model uses "id" has the default id attribute name. You can specify a different name by overriding the idAttribute property of the model. Whatever the name, it is always automatically made available through the model.id property.
Now, assuming the id attribute isn't related to this model and this model's real id attribute name is something like UID, you could change the idAttribute of the model to reflect the real name of the attribute (or it could even be a string that's never going to be an attribute).
var MyModel = Backbone.Model.extend({
idAttribute: 'UID',
});
Now, the id attribute is not considered an id for the current model, and model.isNew() will return true, sending a POST request to create it on save.
Change the sync/save function behavior
If the API you're using is not RESTful, you can adjust the behaviors by overriding the sync function. This can be done on the model or collection, or on the Backbone.sync function which is used by default by the collections and models.
For example, if you wanted to make every request use POST by default for MyModel class:
var MyModel = Backbone.Model.extend({
sync: function(method, model, options) {
return Backbone.sync.call(this, method, model,
_.extend({ type: 'POST' }, options));
}
});
You could do something similar with only the save function to let the fetch do its GET request as usual.
Use the emulateHTTP setting2
If you want to work with a legacy web server that doesn't support
Backbone's default REST/HTTP approach, you may choose to turn on
Backbone.emulateHTTP. Setting this option will fake PUT, PATCH and
DELETE requests with a HTTP POST, setting the X-HTTP-Method-Override
header with the true method.
[...]
Backbone.emulateHTTP = true;
model.save(); // POST to "/collection/id", with "_method=PUT" + header.
Do not override isNew
Has this model been saved to the server yet? If the model does not yet
have an id, it is considered to be new.
Some other answers on this site suggest overriding the isNew function. Don't. The function has its purpose and overriding it to force a POST request is a poor hack, not a solution.
isNew is used internally but can also be used by your code or other libraries and Backbone plugins.
1 While I did not take this from stack overflow, it was already an answer by Andrés Torres Marroquín on a similar question.
2 Taken from Maanas Royy's answer.

How can I pull a new request from my index with Backbone.js?

I have an index that creates randomly generated dynamic content.
So everytime you load the index, it'll create a series of view that are dependent on what my Rails model has produced and sent to Backbone.
From backbone, I am curious what I could do to "refresh" the page without doing something like this :
window.location = '/'
I'd like to do it within Backbone.. something like this :
Backbone.history.navigate('/', {trigger: true, replace: true});
But this doesn't necessarily send a new request to the url.
All I would need to do to accomplish my goals is send a GET request to /, which should return a JSON object I can pipe through the rest of my Backbone app.
Is there a way to send this request within Backbone? Or should I just go a traditional jQuery route, and just make a $.get request?
Since your REST api returns a JSON object, simply use a Backbone.Model to structure this data. You can then bind events to do whatever you like in your application.
var RandomData = Backbone.Model.extend({ url: '/' });
var randomData = new RandomData();
// Here, `Backbone` can be substituted by any `View`, `Collection`, `Model...
Backbone.listenTo( randomData, 'change', function() {
//Do something everytime this changes.
});
// When you need to issue a GET '/' request. The following will put the
// JSON response inside of `randomData.attributes`
randomData.fetch();

Categories