I'm trying to understand how to remove an item from my Firebase. I've set up a function (saveEmployee) to create an item , but can't figure out how to go about removing an item.
HTML
<tbody ng-repeat="employee in employees">
<tr>
<td>{{employee.employeeName}}</td>
<td>{{employee.employeeAge}}</td>
<td><a class="btn btn-danger" ng-click="removeEmployee(employee.employeeName)" >Delete</a></td>
</tr>
</tbody>
JS
$scope.removeEmployee = function(employeeName) {
console.log(employeeName);
$scope.myData.child(employeeName).remove();
};
Use Firebase.set() and pass in null. This will delete the employee.
$scope.removeEmployee = function(employeeId) {
var employeeRef = new Firebase('https://myfirebaseurl.firebaseio.com/employees/' + employeeId);
employeeRef.set(null);
};
or with a callback handler.
$scope.removeEmployee = function(employeeId) {
var employeeRef = new Firebase('https://myfirebaseurl.firebaseio.com/employees/' + employeeId);
employeeRef.set(null, function(error) {
if (error) {
console.log(error);
} else {
console.log('Employee deleted.');
}
});
};
Related
I have implemented a REST service with Java and all HTTP methods work correctly when I test it with Postman. Now I decided to learn more about AngularJS and added it for consuming the REST service. The GET request works fine and all products are displayed on an html page. But for some reason Delete and Put methods do not work at all. And I'm having trouble to figure out what causes such behaviour.
I have noticed that the problem arises with methods that involve product id. The entity Product.java has an id field named prod_id.
app.js
angular.module("AppProducts", [])
.constant("baseUrl", "http://localhost:8080/webstore/product")
.controller("ProductsCtrl", function ($scope, $http, baseUrl) {
$scope.currentView = "table";
//Works correctly
$scope.showAll = function () {
$http.get(baseUrl).success(function (data) {
$scope.products = data;
});
}
//if product exists, copy it, otherwise new empty
$scope.editOrCreate = function (product) {
$scope.currentProduct = product ? angular.copy(product) : {};
$scope.currentView = "edit";
}
$scope.create = function (product) {
$http.post(baseUrl, product).success(function (product) {
$scope.products.push(product);
$scope.currentView = "table";
});
}
$scope.update = function (product) {
$http({
url: baseUrl + product.prod_id,
method: "PUT",
data: product
}).success(function (modifiedItem) {
for (var i = 0; i < $scope.products.length; i++) {
if ($scope.products[i].prod_id == modifiedItem.prod_id) {
$scope.products[i] = modifiedItem;
break;
}
}
$scope.currentView = "table";
});
}
$scope.delete = function (product) {
// HTTP DELETE
$http({
method: "DELETE",
url: baseUrl + product.prod_id
}).success(function () {
$scope.products.splice($scope.products.indexOf(product), 1);
});
}
// Save changes
$scope.saveEdit = function (product) {
if (angular.isDefined(product.prod_id)) {
$scope.update(product);
} else {
$scope.create(product);
}
}
$scope.cancelEdit = function () {
$scope.currentProduct = {};
$scope.currentView = "table";
}
$scope.sortType = 'brand'; // set the default sort type
$scope.sortReverse = false; // set the default sort order
$scope.searchProduct = ''; // set the default search/filter term
$scope.showAll();
});
'table' view
<table id="myTable" class="table table-hover">
<thead>
<tr>
<th>Brand</th>
<th>Product Name</th>
<th>Description</th>
<th>Price</th>
<th width="100"></th>
<th width="100"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in products | orderBy:sortType:sortReverse">
<td>{{product.brand}}</td>
<td>{{product.productName}}</td>
<td>{{product.description}}</td>
<td>{{product.price}}</td>
<td><button class="btn btn-success" ng-click="editOrCreate(product)">Edit</button></td>
<td><button class="btn btn-danger" ng-click="delete(product)">Delete</button></td>
</tr>
</tbody>
</table>
RestController 'delete' method
#RequestMapping(value = "/product/{id}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteProduct(#PathVariable("id") int id) {
Product product = productService.getProductById(id);
if (product == null) {
return new ResponseEntity(new CustomError("Unable to delete. Product with id " + id + " not found."),
HttpStatus.NOT_FOUND);
}
productService.deleteProduct(id);
return new ResponseEntity<Product>(HttpStatus.NO_CONTENT);
}
This may be the problem. When you are appending the url like this
baseUrl + product.prod_id // let product.prod_id = 1
you would get resulting string as http://localhost:8080/webstore/product1 which is not defined in your backend. Try changing the assignment to something like this:
baseUrl + "/" + product.prod_id
Or you cold just add an / at end of baseurl. Like this:
.constant("baseUrl", "http://localhost:8080/webstore/product/")
I am trying to delete this entire row whenever you click the Delete button. This is my jQuery command:
UPDATE: I have updated the click function to my finalized version:
$(document).on('click', '.delete-assignment',function () {
console.log("click");
var data = {
assignment_id: $(this).closest('tr').find('.assignment-id').html(),
class_id: $('#classId').val()
}
var row = $(this).closest('tr');
deleteAssignment(data, function(returnData){
var returnData = JSON.parse(returnData);
if(returnData.status == "Success"){
console.log("yes");
row.hide();
}
});
});
When I click delete, it triggers the deleteAssignment function successfully and returns a callback of {"status":"Success"}. Yet when I returnData.status == "Success" is not being triggered.If I try jQuery.type(returnData), It says string. So I implemented JSON.parse and it says unexpected token in json at position 0
here is my html:
<tbody id="Homework">
<tr>
<td>Homework Test Title</td>
<td>02/16/2017 - 10:00 AM</td>
<td class="assignment-id">51</td>
<td><button type="button" class="btn btn-danger delete-assignment">Delete</button></td>
</tr>
</tbody>
I wanted to also include how I am passing data back to deleteAssignment as a callback (defined in the javascript function (deleteAssignment)
assignment = Assignments.objects.get(id=data['assignment_id'])
assignment.delete()
data = {}
data['status'] = "Success"
return HttpResponse(json.dumps(data), content_type="application/json")
You have a clouser problem.
The variable this inside your callback function is not the same this that inside the click function.
There are several ways to solve this, here is one of them:
$('.delete-assignment').on('click', function () {
var data = {
assignment_id: $(this).closest('tr').find('.assignment-id').html(),
class_id: $('#classId').val()
}
var that = this;
deleteAssignment(data, function(returnData){
console.log(returnData);
if(returnData.status == "Success"){
print("yes");
$(that).closest('tr').remove();
}
});
});
For each make and model added via the "add" button, I need to check for a duplicate, set an alert if there is a duplicate and not let it add to the table. Cannot seem to find the solution...
Below is the entire code for the beginner project I am working on. My apologies ahead of time for this post, it is my first here... Thanks all.
<div>
<div>Make: <input type="text" ng-model="make"></div>
<div>Model:<input type="text" ng-model="model"></div>
<button ng-click="add()">Add</button>
<tr>
<th>Make</th>
<th>Model</th>
</tr>
<tr ng-repeat="car in cars" ng-click="rowClick(car)">
<td>{{car.make}}</td>
<td>{{car.model}}</td>
</tr>
<table class="table carsTable">
<tr>
<th>Make</th>
<th>Model</th>
</tr>
<tr ng-repeat="car in cars" ng-click="rowClick(car)">
<td>{{car.make}}</td>
<td>{{car.model}}</td>
</tr>
<script>
var carsApp = angular.module('carsApp', []);
carsApp.controller('carController', function ($scope){
$scope.cars = [];
$scope.add = function () {
$scope.cars.push({
make: $scope.make,
model: $scope.model
});
$scope.make = null;
$scope.model = null;
};
$scope.rowClick = function(car){
$scope.make= car.make;
$scope.model= car.model;
};
$scope.alert = function(){
alert('Already exists in table');
}
});
You can check for duplicates by checking each car in your array (comparing the make and model) - you can accomplish this with Array.some (returns a boolean if any of the elements in the array match the condition):
In your add function:
var hasDuplicates = $scope.cars.some(car => car.make == $scope.make && car.model == $scope.model);
if (hasDuplicates) {
alert("Car already exists");
} else {
$scope.cars.push({
make: $scope.make,
model: $scope.model
});
}
If you can't use arrow syntax:
var hasDuplicates = $scope.cars.some(function(car) {
return car.make == $scope.make && car.model == $scope.model;
});
$scope.add = function () {
let dataToAdd = {
make: $scope.make,
model: $scope.model
};
let alreadyAdded = $scope.cars.some((o) => angular.equals(o, dataToAdd ));
if (alreadyAdded) {
$scope.alert();
return false;
}
$scope.cars.push(dataToAdd);
$scope.make = null;
$scope.model = null;
};
I have a api call who give me the list of data, and I am iterating data via ng-repeat (its a list of more than 100 items)
For getting list of data I have call an Api in App Controller in angularjs like this:
var path = serverUrl + 'api/getAllMails';
$http.get(path).then(function (result) {
$scope.mails=result
})
For Iterating the mails in Html file i have use table like the below
<table>
<tr class="header">
<th class="center">Id</th>
<th class="center">Mode of Payment</th>
<th class="center">Payment Collected</th>
<th class="center">Status</th>
</tr>
<tr ng-repeat="mail in mails">
<td>{{mail.id}}</td>
<td>{{mail.paymentType}}</td>
<td>Rs. {{mail.cost}}
<input type="text" ng-model="mail.cost">
<button ng-click="updateCost=(mail.id, mail.cost)">Update Cost</button>
</td>
<td>{{mail.status}}
<input type="text" ng-model="mail.status">
<button ng-click="updateStatus(mail.id, mail.status)">Update Status</button>
</td>
</tr>
</table>
Suppose in the first iterations the cost will be "100" and the status will be "pending". And I have to update this row only, change cost to "1000" and status will be "Delivered".
In my App controller of Angularjs I have create methods. These two methods are calling apis and updating data in database and return the list of updated mails.
$scope.updateStatus = function(mailId, mailStatus) {
var path = serverUrl + 'api/updateStatus';
$http.get(path, {
params: {
mailId: mailId,
mailStatus: mailStatus
}
}).then(function(result) {
$scope.mails = result
})
}
$scope.updateCost = function(mailId, mailCost) {
var path = serverUrl + 'api/updateStatus';
$http.get(path, {
params: {
mailId: mailId,
mailCost: mailCost
}
}).then(function(result) {
$scope.mails = result
})
}
These code are working fine but while it took lot of time to load a page. So what can I do to reduce the loading time or is there any better way to do the same thing.
Any help will be appreciable. Thank you
You are replacing the entire dataset when there is no reason for that, you should only update the row you change. Ensure your updateStatus return the object you update and update that item in $scope.mails
In example
$scope.updateCost = function(mailId, mailCost) {
var path = serverUrl + 'api/updateStatus';
$http.get(path, {
params: {
mailId: mailId,
mailStatus: mailCost
}
}).then(function(result) {
// result is the item you changed
for (var i = $scope.mails.length - 1; i >= 0; i--) {
if($scope.mails[i].id === mailId) {
$scope.mails[i] = result;
return;
}
};
})
}
I am in the process of learning about knockout/json/mvc et al and have tried to put together an example project, but for some reason I am unable to get the data to bind correctly.
In the code snippet below, I get some JSON data from a web server and then try to map it to a function and then eventually to my knockout observableArray. What I then do is use this observableArray to bind to a HTML table. However the HTML table is not displaying any data. I put a label on to the HTML page and this does print out but with a toString() value of :
[Object object]
five times, which matches the amount of properties in the JSON data.
Can anyone see anything obvious I am missing?
JSON received from web server:
{ "Id": 1, "Name": "Inst123", "Price": 10, "DateTime": "2014-01-16T17:22:43.6383507+00:00", "Description": "Descriptions" };
.
ViewModel
$(document).ready(function () {
var gtViewModel = new GvTradeViewModel();
ko.applyBindings(gtViewModel);
console.log("ViewModel created");
});
var GvTradeViewModel = function () {
var self = this;
self.gvTrades = ko.observableArray([]);
var apiUrl = "http://localhost:57858/api/Trade/1";
console.log("Starting JSON data retrieval from: " + apiUrl);
$.getJSON(apiUrl)
// Handle success event.
.done(function (jsonData) {
if (jsonData.isEmptyObject)
console.log("NoData recieved");
else {
console.log("JSON data: " + jsonData);
var mappedTrades = $.map(jsonData, function (gvTradeData) {
return new GvTrade(gvTradeData);
});
self.gvTrades(mappedTrades);
console.log(self.gvTrades);
}
})
// Handle error/fail event.
.fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log("Request Failed: " + err);
});
};
function GvTrade(data) {
this.TradeId = ko.observable(data.TradeId);
this.InstrumentName = ko.observable(data.InstrumentName);
this.DateTime = ko.observable(data.DateTime);
this.Price = ko.observable(data.Price);
this.Description = ko.observable(data.Description);
}
HTML
<table>
<thead>
<tr>
<th>TradeId</th>
<th>InstrumentName</th>
<th>Price</th>
<th>DateTime</th>
<th>Description</th>
</tr>
</thead>
<tbody data-bind="foreach: $data.gvTrades">
<tr>
<td data-bind="text: InstrumentName"></td>
<td data-bind="text: Price"></td>
<td data-bind="text: DateTime"></td>
<td data-bind="text: Description"></td>
</tr>
</tbody>
The JSON coming from your server represents a single object and not an array.
So when you are calling $.map then it does not correctly maps your data as an array, so you will end up some unusable objects.
To fix this you need to make sure that your jsonData containing an array before the map operation, you can do this with calling jQuery.makeArray on it (or you can have an if which is based on your data type decide whether you need to map or not):
var mappedTrades = $.map($.makeArray(jsonData), function (gvTradeData) {
return new GvTrade(gvTradeData);
});
Demo JSFiddle.