Deleting Specific Record Using ObjectID - javascript

I'm defining a delete function in which, there's a delete button in each row, sending the ObjectID of that specific record to my Server Side, therefore, this ObjectId will be checked with the one stored in the database, resulting in deletion of that certain record, so far I could have make a good progress sending data's over, and checking on it, but I"m suspecting the ObjectId being sent, requires some sort of casting. Currently, the code and responses are as below;
Front-End (Index.Html)
<a href="#" class="list-group-item active" >
List Of Notes
</a>
<a href="#" class="list-group-item" ng-repeat="r in retrieve" >
{{r.create_at}}
<button style="float:right" type="button" ng-click="delete_note(r.ObjectId)"
class="btn btn-danger btn-xs">
Delete <i class="fa fa-trash"></i>
</button>
</a>
AngularJS (main.ctrl.js)
$scope.delete_note = function (data_id) {
$http.get('/delete_note', {
params: data_id
}).success(function(data){
console.log(data)
});
}
Back-End (Root.py)
#cherrypy.expose
#cherrypy.tools.json_out()
#cherrypy.tools.json_in()
def delete_note(self,*args,**kwargs):
res2=self.my_app.delete_note(kwargs)
return "<h1>delete success </h1>" +str(res2)
pass
Back-End (App.py)
def delete_note(self, index):
return self.db.notes.remove({'_id': index})
The current message appears in Google Chrome Console.log is this :
<h1>delete success </h1>{'ok': 1, 'n': 0}"
Which is obviously stating that, nothing has been changed within the database, I'm using Cherrypy, Mongodb, and Angularjs, any consideration is appreciated.

It'll be hard to locate the exact problem, but there are a few things that call for attention:
As nnnnnn already pointed out, nesting a button in an anchor (a) element is odd and might lead to weird issues.
The directive ng-click="delete_note(r.ObjectId)" looks odd: Does your python code really remap the _id field to a field called ObjectId? ObjectId is the type of (default) keys in MongoDB, the convention for the name is _id.
To find out, take a look at the network inspector when you GET the original data (i.e., $scope.retrieve) - what does it send? It's also helpful for debugging to output <pre>{{retrieve | json}}</pre> so you can see what ends up at angular
You're apparently deleting using a GET. While there's nothing that prevents you from doing that, writing with GETs is bad practice. If you possibly can, delete using an HTTP DELETE. If that's completely impossible for whatever reason, at least use a POST. But a GET should be nullipotent, i.e. it shouldn't change the server state at all.
The parameter to a REST request should be part of the URL, so your delete should read
DELETE /notes/:noteId, e.g. DELETE /notes/54fadec1e4259ded64c7576a
Putting the identifying parameter somewhere else violates the idea of resource urls.

Related

Backbone save() method Post insead of Put

I'm trying to update data on backbone.But my save() function post insead of put.
editEvent:function(e){
var departments=new Department();
departments.set("departmentName",this.$el.find(".departmentName").val());
departments.save();
this.render();
},
departmentModel
var Department = Backbone.Model.extend({
urlRoot: "/rest/department",
idAttribute:'departmentID'
}
});
return Department;
template
<th>
<span>{{user.department.departmentName}}</span>
<input data-placement="top" title="Boş geçilemez!" class="form-control text-center departmentName" type='text'
style='display: none;' value='{{user.department.departmentName}}'/>
</th>
That's by design, here's a snippet from the Backbone docs for the save function:
If the model isNew, the save will be a "create" (HTTP POST), if the
model already exists on the server, the save will be an "update" (HTTP
PUT).
Model is considered 'New' if it does not have an id.
Since you're creating the model for the first time, Backbone will use the POST method as it should, because it means you're creating a new resource. For more info on the meaning of HTTP verbs.
My suggestion would be solving this on the server side and making separate handlers for POST and PUT, but if you really want to force PUT method, here are some tips: What is the least ugly way to force Backbone.sync updates to use POST instead of PUT?
I solved the problem with using id.If you try PUT request without id,backbone think "it's a new model".But you save with data's id value, backbone think PUT request.
That's why i tried put request with id and that's worked.
departments.set("departmentID",this.$el.find(".departmentName").data("id"));
departments.set("departmentName",this.$el.find(".departmentName").val());
departments.save();

Ajax requests, database and security

This post is more a question than an actual issue with code.
So for a long time when I had to display for example a list of items from database, I used to display the Id (primary key in the table) directly in the HTML like this for example :
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
So like this when I wanted to do an Ajax request of the current clicked item, it was easy because I just had to retrieve the attribute from the html like this :
$.ajax({
url: '/api/Item/'+$(this).attr('id'),
type: 'GET',
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
That's only after browsing a lot of websites that I noticed that nobody display the primary key (Id) directly in the HTML. But somehow they could still do ajax request to the API using the Id of the clicked item. So my question is : How can I get the current clicked Id to do my ajax request without displaying anywhere. I mean how does these websites manage to do that ? Maybe they get list from server that they use in the client then ? But it still does not explain how they manage to get the current clicked Id.
Appreciate your thoughts and suggestions on this.
Example of website : https://www.toneden.io/
The chat at the bottom right when connected see network and web browser console.
To get response from the server, you have to request something. In this case, you are saying i don't want to display primary key anyware in html side and get result from server. my suggestion on this, In php > you can use binary number instead of primary key and convert back to number and use acc. to requirements. Example :- decbin() and bindec()
There's nothing wrong with displaying an id. I've appended the database id such as id="game_1281" in cases where I only want to refer to the DOM in response to a server push update. Another option is to use a data attribute like so: data-id="1281". This allows you to get the value without any messy parsing before sending it to the server.
Referencing a unique id is not a security issue. Just make sure you are doing the appropriate server-side checks to ensure that the action taken is possible for that user based on various constraints and privileges.

Laravel URL Generator With Angular JS Varible

I am making an application with Angular JS as frond end and Laravel as back end.
I having a list of master data table view and a delete and edit options.
<a class="resedit btn btn-sm btn-default" href="{{URL::route('edit_repair_category',[[category.id]])}}/"><i class="icon-note"></i></a>
<a title="Delete" ng-click="deleteRow($event,category.id,'{{URL::route('delete_repair_category')}}',currentPage)" class=" btn btn-sm btn-delete"><i class="glyphicon glyphicon-trash"></i></a>
Above I am generating URL of Edit page with Laravel URL Generator, But I want to pass the ID of the master data to fetch the data from controller.
I am using [[ ]] for Angular JS bindings.
URL::route('edit_repair_category',[[category.id]])
Now I got the exception Use of undefined constant category - assumed 'category'
Routes.
Route::get('edit-repair-category/{id}', ['as' => 'edit_repair_category', 'uses' => 'RepairCategoryController#editRepairCategory']);
Is there any possibilities ?
The reason you're getting this error is because you're mixing javascript and PHP.
The PHP portion of you code is going to be processed on the server and then passed to the browser where the javascript is then going to be processed, so as far as PHP is concerned you are trying to use a constant.
Since category.id is just going on the end of the url you should be able to do something like:
<a class="resedit btn btn-sm btn-default" href="{{ URL::route('edit_repair_category', null) }}/#{{category.id}}"><i class="icon-note"></i></a>
null is being used here to prevent an error being thrown.
The # before {{category.id}} just tells blade to treat this like a normal string and not to do anything with it (the # symbol will be remove by blade).
Hope this helps!

Why does an AngularJS form post sometimes have one parameter empty?

I have a quite large AngularJS application and one of the forms is giving me trouble. On this form users can write messages that are saved on the server into the database. However, 20% of the time, some kind of error is causing the message to be blank. I can see these empty messages in the database.
As far as I can tell the problem is happening on the client not the server. (My evidence for this is that I've added code on the server that logs all the form data the moment that the web request is received. When blank messages are saved into the database, I can see that the message text was already missing in these logs right at the start of the server-side process.)
So, I think it may be something to do with the way I send the data from the client. My JavaScript is as follows...
var params = {
"slotid": self.slot.slotid,
"personid": self.personid,
"message": self.slot.message
};
$http({
method: 'POST',
url: '/restapi/confirmationmessage.aspx',
data: $.param(params),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
When it works, the form data on the server looks like this:-
slotid=SOME-GUID8&personid=ANOTHER-GUID&message=the+message+goes+here
When it fails it looks like this:-
slotid=SOME-GUID8&personid=ANOTHER-GUID&message=
The web page that accepts the message input is written using Bootstrap and the relevant fragment is below. The submit button is disabled if the textarea box is empty, so blank messages shouldn't ever happen!
<div class="form-group">
<textarea class="form-control" ng-model="slot.message" placeholder="Enter your message here..." rows="8"></textarea>
</div>
<button type="button" ng-click="ctrl.areyousure('message', slot, '');" ng-disabled="slot.message==''" class="btn btn-default">
<span class="glyphicon glyphicon-envelope"> </span>
<span>Send message</span>
</button>
In case it helps, my back-end is written in ASP.NET using C#.
Can anyone explain why the message parameter is sometimes empty? It is an intermittent fault, so I think it might have something to do with unusual characters in the message, but I've tried, commas, quotes, double quotes, and semi-colons, but they all worked fine. Could it be a limitation in the function $.param()?
It would also be useful to get some suggestions about how I could add some logging to my client-side code to help diagnose the problem, or any similar idea to help me solve this.
Thanks in advance.
Adam
your initial value for slot.message will be either null or undefined, so you should add those cases as well.
But this is not the right way checking for required value. You should use ng-required attribute, here is an example of using form-ng-required Angular form validation ng-disabled not working

ASP.NET MVC / JQuery/ Javascript: view will not refresh after searching (and trying to load) new data

This is my first post of stackoverflow. I've spent the past month trying to solve this on my own, extensively searching Google and this website. Here's my problem:
I have a website where users can search for cases. When they find a case, their results are loaded on a case details page. Users normally search for cases from the homepage by clicking a search option, where they enter a case number like the following:
14-12345
Users submit their search to the homepage's index controller. The controller parses the search and redirects to a "case" action. This action polls the database to get case details, and returns a case view.
This search works - users see the results of their search on a case details page. However, a request was received so users can search for cases from the case details page as well.
I can't make the new request work. I've tried using Web API (which really became a waste of time, because I want to return a whole view, not just search data), and I've failed to create the appropriate controller/view combination to work with my data. I usually wind up trying to use the existing controller (which has the code to search) and the case details view.
Breaking down the pieces...
The model data is stored in a viewmodel file:
public class PortalCaseView
{
public DocketCase CaseInfo { get; set; }
public List<CaseNote> Notes { get; set; }
public string Search { get; set; }
...other various variable declarations, etc
}
The Index.cshtml file is the homepage/main landing page for the site. Users can search for case details by going to a section to search (code from the view here):
<div class="tile">
<span>Search by Case Number</span>
#Html.EditorFor(x => x.Search)
<a class="m-btn green-stripe" href="javascript:submitForm();" style="color: #444;
text-decoration: none;">Submit<i class="icon-hdd"></i></a> <a class="m-btn red-stripe"
href="javascript:toggleSearch();" style="color: #444; text-decoration: none;">Cancel<i
class="icon-remove"></i></a>
</div>
(Submitting the result gives a submit command, which posts the search to the controller.)
The PortalController.cs controller file directs requests for the homepage. Its Index method grabs the Search variable, and redirects to a Case action to process:
Index
if (!string.IsNullOrWhiteSpace(viewmodel.Search))
{
...
return RedirectToAction("Case", new { Year = docketnumber[0], Sequence = docketnumber[1], J = viewmodel.JudgeCode });
}
Case
[HttpGet]
public ActionResult Case(int Year, int Sequence, string J)
{
...various declarations and requests to get db information...
return View(vm); //vm is a viewmodel with info for the case view
}
[HttpPost]
public ActionResult Case(PortalCaseView vm)
{
return View(vm);
}
* When the redirect to the Case action is complete, the Case.cshtml view loads with the necessary details. Now that searches from the case view are required, I've added a section to the case view to take an "on-demand" search query:
<textarea id="searchForCase" style="width: 150px;"></textarea>
<a class="m-btn green-stripe" href="javascript:searchCase();" style="color: #444;
text-decoration: none;">Search<i class="icon-hdd"></i></a>
And here is where problems start. During a typical run, Ajax/JSON code builds a call back to a controller action. Then, the action executes (usually on data stored in a file or folder). A view is returned, and then the page refreshes. (This is when a user is using the site.) It doesn't work the same way for my new custom code.
My custom searchCase() function takes the case number entered by a user to search for it (it goes back to the Index action in the original PortalController.cs file):
var searchCase = function () {
var textArea = document.getElementById("searchForCase");
var txt = String(textArea.value);
jQuery.ajax({
type: "POST",
url: "#Url.Action("Index","Portal")",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ fromCaseSearch: txt }),
success: function (data) {
alert(data);
},
failure: function (errMsg) {
alert(errMsg);
}
});
$('form').submit();
}
(Note: I've already tried changing the datatype from json to html; I'm assuming I might need to work with the content type)
I've traced the progress from this point. The website goes back to PortalController.cs and to the Index action (following through like a good POST), and then takes the search query provided by the user. Since it falls out of the Index action when I try to redirect to the Case action like before, I added an if statement to deal with search queries directly from the case details view:
if (!string.IsNullOrEmpty(fromCaseSearch))
{
System.Web.HttpContext.Current.Session.Clear();
//forget why I put that clear request there, but I do
//use session state variables, so I might need to clear
//them when searching from scratch - if they exist
viewmodel = new PortalIndexView();
viewmodel.Search = fromCaseSearch;
...initialization and parsing for search...
...searching for and loading data from database(s)...
ModelState.Clear(); //was hoping this would "refresh" view
//...this didn't work either
return View("Case", vm); //forced website to return
//case view with viewmodel data
//...this actually starts loading
//the case view
}
This actually works... to a point. The data gets processed the same way, and the case view is loaded like normal. However, even after tracing the loading process (and seeing that model variables are sent to the view), the page does not update with the new information).
So, that's where I'm stuck. I've tried tweaking some settings (and even thought the problem might be in the web.config file), but when I run across problems like this, what usually fixes the problem for me is to find out what I did wrong here (or in the general vicinity of the problem - the answers usually happen when I fix simple stuff first).
Some last-minute things:
PortalController.cs (the controller) outputs to Case.cshtml (the case details view). When right-clicking the View controller action, it redirects back to PortalController.cs (the main controller from the landing page).
No other controller shares Case.cshtml.
There is no CaseController.cs file. It looks like my predecessor simply created the search "redirect", figuring users would only search from the homepage (and they did up until now).
Last-second idea? Maybe I'm supposed to account for HTTPGet and HTTPPost actions for my new code as well. Not sure... brain is mush...
Naturally, since this is a work project, I can only provide so many details, but I'll be glad to take suggestions at this point.
UPDATE: is it possible that my problem is because I didn't include a #using (Html.BeginForm(...)) line in my case details view? I noticed there isn't one. Do you need one to be able to have official POST action in the related controller?
One other clarification: I'm using Ajax/JSON for passing data back to the controller from the case view, since I can't get the page to just "submit" (in Javascript/JQuery code, $('form').submit() does not work at all). I'm wondering if it has anything to do with Web API. (There is a Web API file called CaseNoteController.cs that handles notes that get added to cases. When I was trying to work with Web API - and possibly return a view using it - I had a test api call that made the case details view page refresh effortlessly; I just couldn't figure out how to get it to work for my needs.)
Problem solved (my fault). My lack of experience kept me from figuring this out sooner:
I wound up not needing the searchCase function in the Case view. The reason why: I didn't wrap my Case view in a #using(Html.BeginForm()) code block, which meant that my page wasn't posting results (no matter how hard I tried)
I didn't pay attention to my PortalController.cs file, which already had HttpGet and HttpPost variants of my Case action. (The HttpPost action was completely empty, save for returning a view. That explains why the page failed to load and display anything, let alone the results of my next case search.)
Once I corrected those issues (and tweaked a few other buttons so they didn't automatically post or try to run when I submitted the document), the code finally worked! Praise God. No need for convoluted or weird paths back to the controller - things happened real quick after that.
(Now to trim off a whole bunch of scaffolding and otherwise unnecessary code...)

Categories