AngularJS Delete function REST HTTP://1.1 500 Error - javascript

I am using AngularJS to delete a row via a REST API. When I click the link for the function to delete the row, I get a Internal Server Error. I'm asking how to fix the form to get it to delete the row.
//CONTROLLER to delete a specific item
countryApp.controller('DeleteLocation', function($scope, $http, $routeParams, $location) {
//get item info
var id = $routeParams.locid;
$scope.activePath = null;
$http.get('http://localhost/slimtest2/location/'+id).success(function(data) {
$scope.location= data;
});
//add more stuff here
$scope.pedelete = function(id) {
$http.delete('http://localhost/slimtest2/location/1/delete', id);
}
});
View for Deleting a Row
<div ng-controller="DeleteLocation">
<div ng-repeat="l in location.location">
Are you sure you want to delete the location named: {{l.location_title }}
Delete This
</div>
</div>

Internal Server error occurs when something happens wrong at server-side. Please check your server-side code/configuration are proper or not.

A couple of points to check:
1. Is your request method type "get" for a delete request as well or should it be "delete"? For this you need to check which method type your API is expecting. You may want to use $http.delete() instead.
2. Check your browser console/network. Are you seeing the error there? If so, work out on the error to resolve the issue. The error description should be coming what your API is sending.
Hope this helps.

Related

ng-repeat not displaying data from http request. getting commented when inspecting [duplicate]

This question already has answers here:
How to enable CORS in AngularJs
(10 answers)
How does the 'Access-Control-Allow-Origin' header work?
(19 answers)
Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not?
(13 answers)
Closed 4 years ago.
My
homeController.js
var app = angular.module('myApp');
app.controller('HomeController',
function($scope, $http, $rootScope, $stateParams, $state, LoginService) {
$scope.user = $rootScope.userName;
console.log("Starting http request");
$http.get("http://127.0.0.1:5000/trying").success(function (response) {
$scope.myData = response.users;
console.log(response);
});
console.log("ending http request");
});
<div class="col-md-12" style="width:500px;">
<div align="right"><a ui-sref="login">Logout</a></div>
<h4>Welcome {{user}}! </h4>
<p><strong>This is Home Page</strong></p>
<ul>
<li ng-repeat="x in myData">
Data are : {{ x.fname + ', ' + x.coordinates }}
</li>
</ul>
</div>
Console
Response object
The home.html is getting rendered from index.html. It is doing it fine as can be the user with which am logging in is displaying. However the ng-repeat is not working fine. When inspecting its showing that its getting commented out. What am i doing wrong?
I would make sure that $scope.myData exists outsideof the http.get function. Define it as an array or dictionary/obj right above the http.get function, and under $scope.user... that way the view knows what to expect.
Is myData an array or a dictionary? make sure you are using the correct looping syntax (x in myData vs x of myData). Can also do (dataKey, dataValue) in myData
I usu sally add an ng-if="!isLoading" to the ng-repeat if the contents are dependent on an http call. Initially I set in the this.$onInit function (which gets called automatically once the page is ready to be initialized) then in the response set it to isLoading = false.
`
this.$onInit = function(){
$scope.isLoading = true;
// rest of the stuff like http.get...
$http.get("http://127.0.0.1:5000/trying").success(function (response)
$scope.myData = response.users;
$scope.isLoading = false;
console.log(response);
});
};
`
Let me know if that helps the behavior. of your view, it could also be that the view isn't updating for some other reason.
PRO TIP: When you define your $scope.myData initially, IT MUST be the same type of variable that you are returning if you want ng-repeat to behave correctly.
None of this, "declared as [] but then fills in as a {} later on with an api call".
This is one of those things that can ghost you hard since vanilla javascript is pretty hands off with variable type swapping. The view will just ignore the code smell and not do anything... which can be pretty darn frustrating if you don't know what to look for. This is why some developers have gone off to typescript and other flavors of javascript that are a bit more cemented in what they allow you to do with variable... but that is another post completely.

Catch oData errors from oTable.bindItems

I have a table built up in JavaScript thus:
oTable.bindItems({
path: oQuery,
template: this.getFragment("<fragment>"),
filters: aFilter
});
Is there a way to catch the errors coming back from the odata call in the same way when you do an oModel.read you can specify success and error functions?
This reference seems to not mention it: https://sapui5.hana.ondemand.com/#docs/api/symbols/sap.ui.base.ManagedObject.html#bindAggregation
Perhaps there is something I am missing.
We have 2 methods to check for oData Failure:
attachMetadataFailed. (https://openui5.hana.ondemand.com/#docs/api/symbols/sap.ui.model.odata.ODataModel.html#attachMetadataFailed)
attachRequestFailed.
Let's take up option 2 with an example ( as I'm sure you will have a valid oData Service).
Service: http://services.odata.org/Northwind/Northwind.svc/
Note: Employees is a valid Entity Set in the above Northwind service.
I will try to bind my table with a wrong Enity set name such as : MyEmployees.
Now, binding my table to MyEmployees will throw error which we need to catch. Below is the working code:
View:
<Table items = "{/MyEmployees}">
Controller:
var url = "proxy/http/services.odata.org/Northwind/Northwind.svc/";
var oDataModel = new sap.ui.model.odata.ODataModel(url);
oDataModel.attachRequestFailed(function(e) {
console.log('request failed');
});
this.getView().setModel(oDataModel);
Go ahead and try it. Let me know if this helps. :)

Cannot access proper firebase item key to pass to delete function

Having a sticky issue with firebase. I am trying to get access to the long format ID which firebase auto-generates for each collection item (eg. -JgnIsMlTLaPuDMEtQP2) to pass to my delete function. I previously got it to work in a different angular app as follows:
HTML
<tbody ng-repeat="(key,employee) in employees">
<tr>
<td>{{employee.employeeName}}</td>
<td>{{employee.employeeAge}}</td>
<td>{{key}}</td> // the key param appeared perfectly in this case
<td>
<button class="btn btn-danger"
ng-click="deleteEmployee(key, employee.employeeName)">
delete <span class="glyphicon glyphicon-remove"></span>
</button>
</td>
</tr>
</tbody>
Javascript
$scope.deleteEmployee = function(key,name) {
// get ref to db collectionvar employeeRef = new Firebase("https://xxxxxxx.firebaseio.com/Employees");
// append item key to the path and run remove method
var newRef = employeeRef.child(key);
newRef.remove();
// confirm delete
alert(name + " has been deleted");
}
The above code receives the correctly formatted key and deletes the item perfectly - which is immediately reflected in the view.
However, I'm trying it with a different app and the key value is being set to an incremental index (eg. 0,1,2,3,4...) and so it doesn't work when passed to the delete function. Here is the new code.
HTML
<div class="row">
<ul id="messages" ng-show="messages.length">
<li ng-repeat="(key, message) in messages | reverse">{{message.text}}
<small>{{key}}</small> // WRONG VALUE DISPLAYED HERE
<button class="btn btn-xs btn-danger" ng-click="delMessage(key)" label="Remove">Delete</button>
</li>
</ul>
</div>
Javascript
//delete message
$scope.delMessage = function(messageKey) {
var messageRef = new Firebase('https://xxxxxx.firebaseio-demo.com/messages/');
// append item key to the path and run remove method
var messageRef = messageRef.child(messageKey);
if( messageRef ) {
messageRef.remove();
console.log("DEL: " + messageRef); // this logs the endpoint with index number
console.log("Message removed successfully!");
} else {
console.log("uh oh...problem!");
}
};
The format of messageRef when logged to console is
https://xxxxxx.firebaseio-demo.com/messages/2
but instead should be
https://xxxxxx.firebaseio-demo.com/messages/-JgnIsMlTLaPuDMEtQP2
I have tried every combination that I could find to get it to work but nothing fixes it so far. I'm not sure why it would work in the first piece of code and not the second. The only thing I can add is the app that isn't working was created via firebase-tools in the terminal whereas the working app is just some angular code with firebase bolted on. I have also tried changing remove() to $remove but that throws undefined method errors. I'm totally stumped. Any assistance is appreciated.
Following Frankvan's advice I sourced a snippet from angularFire quickstart docs which allowed me to simply pass the current selected message directly to angularFire's $remove method, avoiding the need to pass a specific message id.
<li ng-repeat="message in messages">
.......
<!-- delete message -->
<button ng-click="messages.$remove(message)">X</button>
</li>
Even though this works, I wanted to add some extra code and decouple the JS from the HTML a bit more. I decided to set up a custom function in the angular controller to handle it and call this function from the ng-click.
The following code works exactly the same as above but adds a prompt for the user to confirm the delete before calling the $remove.
HTML:
<button ng-click="deleteMessage(message)">x</button>
Angular function:
// delete a specific message
$scope.deleteMessage = function(message) {
var msg = JSON.stringify(message.text);
if(message) {
var confirm = window.confirm("Are you sure you want to delete: " + msg + "?");
if(confirm == true) {
$scope.messages.$remove(message).then(function(){
alert("Message " + msg + " has been deleted!");
console.log("Message was removed successfully from firebase!");
});
}
} else {
console.log("Sorry, there was a problem deleting the message.!");
}
};
I beat my head against this problem on a project of mine for awhile. The key is to use the $loaded method of Angular Fire to wait for the object to get populated prior to calling the $remove method because these calls are asynchronous.
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray-loaded

How to make separate copy of JSON and stop it from getting modified in angularjs?

Either I am making a blunder here, or might be misusing Angularjs. I want to make a copy of JSON on page load,create form using original one ,and on submit button press ,I will compare these 2 JSONs to check if they are same or not ,on the basis of that I will hit the DB.
Problem: No matter how I create a copy of JSON, when ever I update field in original json,it get updated in it's copy too. Hence on submit button press , method don't find these 2 json different so don't hit the DB,Data don't get saved.
Code:
var globalJsonHRA =null;
//On succcess of $http
globalJsonHRA = data["3"];
$rootScope.jsonOfHRA = data["3"];
what's wrong with my code??
More Details:
//This is where value is set to JSON on html page
<tbody ng-repeat="obj in jsonOfHRA" my-Post-Repeat-Directive>
<tr class="BG8">
<td ><input type="text" ng-model="obj.sec10_decl_decl_val" id="rent_{{$index}}" ></td>
</tr>
</tbody>
//From making a copy I mean,data["3"] is set to 2 different JSONs, so they are copies of each other. For comparison I was using _.isEqual method of underscoreJs, But even I simply alert these 2 jsons ,I find them containing equal values.
Use angular.copy
$rootScope.jsonOfHRA = angular.copy(data["3"]);
I'm not sure but it is probably the same reference and that's why they change whichever one you modify.
You could try a deep copy.
globalJsonHRA = JSON.parse(JSON.stringify(data["3"]));
$rootScope.jsonOfHRA = JSON.parse(JSON.stringify(data["3"]));
Please write the code into Success callback method of $http
globalJsonHRA = data["3"];
$rootScope.jsonOfHRA = data["3"];
Like
$http.get('/someUrl').
success(function(data, status, headers, config) {
globalJsonHRA = data["3"];
$rootScope.jsonOfHRA = data["3"];
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
and use data after success the $http request.

Can $http.put write data to JSON file

I apologize for the newbie question but I am getting conflicting answers to this while searching on the net.
I have created an AngularJS app to read from a JSON file using $http.get and display the data as a form with each form element binded with ng-model. Ideally I would like the user to be able to edit the desired field and click save, then have that data updated in the JSON file. I have been told that to do this you will need a 3rd party server like NodeJS, but I am seeing other examples that show it being done in videos. Can someone tell me if this is possible without the 3rd party server and if so what is the best practice for doing this.
Thank you
$http GET (for resource located on client) will not work with the Chrome browser and will give a CORS error (unless you disable Chrome web security by opening Chrome using run .../chrome.exe" --allow-file-access-from-files -disable-web-security). Firefox gives an error saying the JSON in not well formed even though it is. Browsers don't seem to like it.
HTML5 LocalStorage is your best bet for client storage where you wish to perform CRUD operations and have the data survive past page refresh. A good example of this is the [TodoMVC example]
(https://github.com/tastejs/todomvc/tree/gh-pages/architecture-examples/angularjs)
A very simple example that saves a json file to localstorage and reads the contents of localstorage is shown. The Service contains a getter and a setter method to interact with localstorage.
INDEX.HTML
<body ng-app = "app">
<div ng-controller="MainCtrl">
<form>
<input placeholder="Enter Name.." ng-model="newContact"/>
<button type="submit" class="btn btn-primary btn-lg"
ng-click="addContact(newContact)">Add
</button>
</form>
<div ng-repeat="contact in contacts track by $index">
{{contact.name}}
</div>
</div>
APP.JS
angular.module('app', ['app.services'] )
.controller('MainCtrl', function ($scope, html5LocalStorage) {
//create variable to hold the JSON
var contacts = $scope.contacts = html5LocalStorage.get();
$scope.addContact = function(contact) {
$scope.contacts.push( {"name":contact} ); //Add new value
html5LocalStorage.put($scope.contacts); //save contacts to local storeage
}
});
SERVICES.JS
angular.module('app.services', [] )
.factory('html5LocalStorage', function () {
var STORAGE_ID = 'localStorageWith_nG_KEY'; //the Local storage Key
return {
//Get the localstorage value
get: function ()
{
return JSON.parse(localStorage.getItem(STORAGE_ID) || '[]');
},
//Set the localstorage Value
put: function (values)
{
localStorage.setItem(STORAGE_ID, JSON.stringify(values));
}
};
});
Otherwise you could use Node and Express and store the JSON file on the server. Use file system module 'fs-extra' to interact with the json file.
You would have to create RESTful API routes for the client to interact with the server using $http and perform CRUD operations.
/put
/get
/delete
/post
I would be interested to see these videos of this being done without the server writing to the file. You cant just "post the .json file" and have it replace the old one, unless you configure your server (apache, nginx, tomcat, node) to do so.

Categories