Error when deleting item from tableview in swift - core-data

I am trying to implement a delete functionality in my app allowing users to delete information stored in core data and presented through a table view.
here is my code:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == .Delete){
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) //error on this line
}
}
the error is as follows:
Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1582
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (6) must be equal to the number of rows contained in that section before the update (6), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
What am I doing wrong? How do I fix this error?

Delete the core data item and let the delegate callbacks take care of deleting the table view row:
if editingStyle == .Delete {
let item = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
self.managedObjectContext.deleteObject(item)
}
The row deletion happens in the delegate callback controller:didChangeObject:atIndexPath: forChangeType:newIndexPath:
if type == .Delete {
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}

Related

Manual Pagination in Cassandra

I use the manual pagination feature in Cassandra.
client.eachRow(query, params, options, function (n, row) {
// Invoked per each row in all the pages
console.log("row",row);
}, function (err, result) {
if(typeof result !== undefined) {
pageState = result.pageState;
console.log("pagestate output : ", pageState);
if(pageState != null) {
//
}
}
}
);
Say we have 4 row / entries in a table 'test'.
When I try to query with fetchsize as '2' It returns two entres with result.pageState then I used the same pageState to query the next page and it fetched successfully.
But the problem is
Since the total entry is 4 and the fetch size is 2, In the get next page, I expect the 3rd and 4th entry with the pageState to be null (Since there is no more entries available) but, It is returning 3rd and 4th entry with another page state.
1) In this Case : Is that the page state received is next value's page state (or) last received value's page state? AFAIK It is the last received value's (4th entries) page state, So to identify that we reached to the last entry, I always make one more call (result.nextpage) and If it is undefined then I consider that there is no more entries available, I feel it is an over head to make one more call for every pagination.
2) How to identify that we reached to the end without making the result.nextpage check.

Outofrange exception when removing items form listview

I have a listview which has multiple rows and check boxes is enabled I tried to wrote a code that remove item when I unchecked the item checkbox as it is checked by default
In the itemcheck event
If(list.Focused == true)
{
If (e.newvalue == checkState.unchecked)
{
list.items.removeAt( e.index);
list.Refresh();
}
}
I got a outofrange exception and 1 is not a valid for index
'1' refer to the index of the item I removed
You have to test if index is in range (because the collection shrink). Add this test before removing elements :
if(list.items.count < e.index && e.index > 0)
Here is the solution in check event you have current value and new value the new value not be applied till the check event is complete if you delete the item the class throw outofrange as it is try to assign a property of deleted item
You can use a list to add the items in and in the event checked remove items and clear the list

How to call SetPropertyException from another event handler?

Below is my code to insert whatever value is entered into my UsrWLAmt field into my BudgetGrid representing the history of the fields values.
I want to raise a warning prompting the user to enter a value into the details field in the BudgetGrid History
protected void PMProject_UsrWLAmt_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e, PXFieldUpdated InvokeBaseHandler)
{
if(InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = (PMProject)e.Row;
PMProject con = Base.Project.Current;
PX.Objects.PM.ProjectExt item = con.GetExtension<PX.Objects.PM.ProjectExt>();
if (item.UsrWLAmt > 0)
{
atcBudgetHis bud = new atcBudgetHis();
bud.CreatedDateTime = DateTime.Now;
bud.Value = item.UsrWLAmt;
BudgetGrid.Insert(bud);
// to attach the exception object to the field
BudgetGrid.View.Cache.RaiseExceptionHandling<atcBudgetHis.details>(
bud, " ",
new PXSetPropertyException(
"Please specifiy reason for budget change.",
PXErrorLevel.Warning));
}
}
I've also tried BudgetGrid.Cahce.RaiseExceptionHandling
The code above doesn't raise any trace errors.
EDIT:
PXUIFieldAttribute.SetWarning<atcBudgetHis.details>(BudgetGrid.Cache, null, "Please specifiy reason for budget change.");
Works for all rows but
PXUIFieldAttribute.SetWarning<atcBudgetHis.details>(BudgetGrid.Cache, bud, "Please specifiy reason for budget change.");
Doesn't raise any warnings.
I could create another field above the grid for the notes to be inserted, but is there a way I can set the warning for the last row in the BudgetGird?
First things first, to show a warning in Acumatica one of the following events must be used:
FieldVerifying and throw PXSetPropertyException, when warning should appear only during the time user updates a record
RowUpdating with RaiseExceptionHandling method invoked on PXCache, if warning should appear on multiple fields only during the time user updates a record
RowSelected with RaiseExceptionHandling method invoked on PXCache, if warning should appear on multiple fields all the time until a user addresses the cause of warning
I guess for your particular scenario, RowSelected might work best to constantly show warnings for all empty cells within Notes column:
public void atcBudgetHis_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
atcBudgetHis row = e.Row as atcBudgetHis;
if (row == null) return;
if (string.IsNullOrEmpty(row.Details))
{
sender.RaiseExceptionHandling<atcBudgetHis.details>(row, string.Empty,
new PXSetPropertyException("Please specify reason for budget change.", PXErrorLevel.Warning));
}
else
{
sender.RaiseExceptionHandling<atcBudgetHis.details>(row, row.Details, null);
}
}
It seems like you tried to set a warning on a DAC instance that didn't exists in the grid at the moment the event was called.
Have you tried setting the warning on the existing row returned in the event handler parameter instead?
PXUIFieldAttribute.SetWarning<atcBudgetHis.details>(BudgetGrid.Cache, row, "Please specify reason for budget change.");
The warning applies to all rows that satisfy the condition that executes this line. If you want to display it for only the last row, you would have to manually check if the row received in the parameter is the same as the last row in your data view and only then execute the warning for that row.
The solution was to use the RowInserted event for my grid and pass the row variable into SetWarning
You need to change this code:
BudgetGrid.Insert(bud);
// to attach the exception object to the field
BudgetGrid.View.Cache.RaiseExceptionHandling<atcBudgetHis.details>(bud, " ",new PXSetPropertyException("Please specifiy reason for budget change.",PXErrorLevel.Warning));
To something like this:
bud = BudgetGrid.Insert(bud); //you need to get the "bud" which is in the cache
// to attach the exception object to the field
BudgetGrid.View.Cache.RaiseExceptionHandling<atcBudgetHis.details>(bud, " ",new PXSetPropertyException("Please specifiy reason for budget change.",PXErrorLevel.Warning));

Coded UI: getcell not working for Wpftable having XamDataGridCustom in the hierarchy

I am new to Coded UI coding so need some help for the below problem I am facing.
I have a WPftable which has the below hierarchy in the UI Map:
this.UICommissionEngineMainWindow.UIXamDataGridCustom.UIRecordsTable
I need to read the cell value from the above table and cells have the below hierarchy:
this.UICommissionEngineMainWindow
.UIXamDataGridCustom
.UIRecordsTable
.UIItemDataItem
.UIItem2443Cell
.UITextBlockText;
When I run the below line of code which has 'GetColumnName' and 'ColumnCount' method it works:
var myrecord = this.UICommissionEngineMainWindow
.UIXamDataGridCustom
.UIRecordsTable.GetColumnNames();
MessageBox.Show(this.UICommissionEngineMainWindow
.UIXamDataGridCustom
.UIRecordsTable
.ColumnCount.ToString());
But when I try to retrieve the cell data it fails. I tried several ways but everytime it fails with
Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException‌​: The playback failed to find the control with the given search properties.
Additional Details:
TechnologyName: 'UIA'
FrameworkId: 'Wpf'
ControlType: 'Cell'
RowIndex: '1'
ColumnIndex: '1'
Search may have failed at 'Records' Table as it may have virtualized children. If the control being searched is descendant of 'Records' Table then including it as the parent container may solve the problem.System.Runtime.InteropServices.COMException: Error HRESULT E_FAIL has been returned from a call to a COM component.
First Try
this.UICommissionEngineMainWindow
.UIXamDataGridCustom
.UIRecordsTable
.GetCell(1, 1)
.Value.ToString());
ALTERNATIVE:
//GetProgramTablehas the Wpftable object in it
var cell = new WpfCell(GetProgramTable());
int row = 1;
int column = 1;
foreach (var data in dataitem.FindMatchingControls())
{
var cell = new WpfCell(data);
cell.SearchProperties.Add(WpfCell.PropertyNames.RowIndex, row.ToString());
cell.SearchProperties.Add(WpfCell.PropertyNames.ColumnIndex, column.ToString());
MessageBox.Show(cell.FindMatchingControls().Count.ToString());
}
ALTERNATIVE:
cell.SearchProperties.Add(WpfCell.PropertyNames.ColumnHeader, "Name");
cell.SearchProperties.Add(WpfCell.PropertyNames.Value, "2143");
MessageBox.Show(cell.FindMatchingControls().Count.ToString())
I am wondering when GetcolumnNames and ColumnCount works why the GetCell doesnt work.

ExecuteNonQuery returning a value of 2 when only 1 record was updated

Running thru examples of Enterprise Library 5.0 and when I use ExecuteNonQuery to run an update sproc, it returns 2. The update is based on ProductID, the table's Primary Key (yes, I checked, and it is unique).
Here is the simple sproc:
ALTER PROCEDURE [dbo].[UpdateProductsTable]
#ProductID int,
#ProductName varchar(50) = NULL,
#CategoryID int = NULL,
#UnitPrice money = NULL
AS
BEGIN
UPDATE Products
SET
ProductName = #ProductName,
CategoryID = #CategoryID,
UnitPrice = #UnitPrice
WHERE ProductID = #ProductID
END
Executing this sp in SSMS shows "1 rows" in bottom right hand corner of the query results window, and a return value of 0 in the grid. Clicking on the messages tab shows
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
not sure why I'm seeing this 3 times here, but I don't believe that is the issue.
Here is the code calling the sp:
public static void Exec_Update_Query()
//updates a column of a single row, checks that the update succeeded, and then update it again to return it to the original value
{
string oldName = "Chai";
string newName = "Chai Tea";
SqlDatabase defaultDB = EnterpriseLibraryContainer.Current.GetInstance<Database>() as SqlDatabase;
// Create command to execute the stored procedure and add the parameters.
DbCommand cmd = defaultDB.GetStoredProcCommand("UpdateProductsTable");
defaultDB.AddInParameter(cmd, "ProductID", DbType.Int32, 1);
defaultDB.AddInParameter(cmd, "ProductName", DbType.String, newName);
defaultDB.AddInParameter(cmd, "CategoryID", DbType.Int32, 1);
defaultDB.AddInParameter(cmd, "UnitPrice", DbType.Currency, 18);
// Execute the query and check if one row was updated.
int i = defaultDB.ExecuteNonQuery(cmd);
if (i == 1)
{
// Update succeeded.
}
else
{
Console.WriteLine("ERROR: Could not update just one row.");
}
// Change the value of the second parameter
defaultDB.SetParameterValue(cmd, "ProductName", oldName);
// Execute query and check if one row was updated
if (defaultDB.ExecuteNonQuery(cmd) == 1)
{
// Update succeeded.
}
else
{
Console.WriteLine("ERROR: Could not update just one row.");
}
}
I'm using int i to view the return value from the method and it returns 2. Any ideas why this would be? This is Enterprise Libarary 5.0 in VS2010 running against SQL 2005. Pretty straightforward but perplexing.
If I recall correctly, the result of any triggers that fire as a result of your commands will also be included in the returned row count. Most likely, this is your issue.
EDIT: Documentation
From MSDN SqlCommand.ExecuteNonQuery:
When a trigger exists on a table being inserted or updated, the return value includes the number of rows affected by both the insert or update operation and the number of rows affected by the trigger or triggers.

Resources