Keep a session variable value after it has been cleared? - asp.net-mvc

Question background:
I have a session object that is used to store a list of object called 'CartItems'. I convert this object to an actual instance, set it to another List variable then finally clear the list. This is then sent to to a ViewBag variable and sent to a View.
The issue:
What I'm trying to do may not be possible but currently as soon as I clear the list instance of CartItems all references to this are lost aswell. Please see the following code:
public ActionResult Complete(string OrderId)
{
//Retrieve the CartItem List from the Session object.
List<CartItem> cartItems = (List<CartItem>)Session["Cart"];
//Set the list value to another instance.
List<CartItems>copyOfCartItems= cartItems;
//Set the ViewBag properties.
ViewBag.OrderId = OrderId;
ViewBag.CartItems = copyOfCartItems;
//Clear the List of CartItems. This is where the **issue** is occurring.
//Once this is cleared all objects that have properties set from
//this list are removed. This means the ViewBag.CartItems property
//is null.
cartItems.Clear();
return View(ViewBag);
}
Can I store this value without losing it after clearing the List?

When you do
ListcopyOfCartItems= cartItems;
You are creating a another variable by the name of copyOfCartItems that points to the same object cartItems. In other words cartItems and copyOfCartItems are now two names for the same object.
So when you do cartItems.clear(); you are clearing all the list items on the base object.
To get around this, make a copy of cartItems, rather than creating a reference
List<CartItems> copyOfCartItems = new List<CartItems>();
cartItems.ForEach(copyOfCartItems.Add); //copy from cartItems

If you want to clear Session["Cart"], use Session.Remove("Cart")

Related

Best way to store and refrence lots data in Swift for use in a UITableView

This is a bit confusing so I apologise. But:
I am trying to make an app where the user has the ability to add items to a list of individual items that will be displayed back to them(Something along the lines of a todo list app) as a table view.
However, I have hit a roadblock I need to store several different bits of data for each item(Some Strings, Some ints and a date) in the list.
I think that a class(or struct) would be the best way to do this where an instance of the class holds the information need for each item and then the name of that instance is stored in a list so it can be accessed via the indexPath in the table view.
However, I don't know how I am going to make a new instance of the class for every item because the app could have hundreds of individual items.
I'm sorry, this is so confusing and any help would be appreciated! Feel free to ask for more info
Edit: what I am looking for and I'm sure there's a stupidly easy way of doing it but I'm try to work out how to create an instance of a class when the name of the class is stored in a variable. Ecencialy I want the instance of the class to store the item. To be created when the user inputs the item to be added to the table.
Eg. They enter an item. item1 and the other data that goes along with then I want to be able to store that in instance of the item class but I don't know how to make the name of that instance because the name I want which is item 1 is stored in a variable.
Sorry that's so confusing that's the reason I need help
So first: You can't store the Name of a Class in a Variable and use this variable to get a new instance of a class.
What you need is an Array containing all the different Items. This array is unlimited so you can store as many items in it as you like and you don't need to set a name for each of these Instances.
First create an empty array containing all Items as a property:
var items : [Item] = []
Second call the function populateItemArray() in your viewDidLoad():
private func populateItemArray() {
// Populate the items Array (Are you using CoreData, Realm, ...?)
}
Third, use the Item Array to populate the TableView.
REMEMBER: If your only using one section in your tableView, indexPath.row is always equal to the corresponding item in the array.
E.G. items[indexPath.row]
Hope this helps you!
UPDATE:
Look at this example struct Item. As you can see you can also store a date in it:
struct Item {
// First create all the properties for your struct.
var data1: String
var data2: Int
var data3: String
// You can create properties of any type you want, also of type date.
var dateOfCreation : Date
// Then implement all the methods of your custom Struct Item.
func setDate(with date : Date) {
self.dateOfCreation = date
}
func returnDate() -> Date {
return self.dateOfCreation
}
}

TempData keep() vs peek()

What is the difference between keep() and peek()?
MSDN says:
keep(): marks the specified key in the dictionary for retention.
peek(): returns an object that contains the element that is
associated with the specified key, without marking the key for
deletion.
I can't get really what the difference is, don't they both keep a value for another request?
When an object in a TempDataDictionary is read, it will be marked for deletion at the end of that request.
That means if you put something on TempData like
TempData["value"] = "someValueForNextRequest";
And on another request you access it, the value will be there but as soon as you read it, the value will be marked for deletion:
//second request, read value and is marked for deletion
object value = TempData["value"];
//third request, value is not there as it was deleted at the end of the second request
TempData["value"] == null
The Peek and Keep methods allow you to read the value without marking it for deletion. Say we get back to the first request where the value was saved to TempData.
With Peek you get the value without marking it for deletion with a single call, see msdn:
//second request, PEEK value so it is not deleted at the end of the request
object value = TempData.Peek("value");
//third request, read value and mark it for deletion
object value = TempData["value"];
With Keep you specify a key that was marked for deletion that you want to keep. Retrieving the object and later on saving it from deletion are 2 different calls. See msdn
//second request, get value marking it from deletion
object value = TempData["value"];
//later on decide to keep it
TempData.Keep("value");
//third request, read value and mark it for deletion
object value = TempData["value"];
You can use Peek when you always want to retain the value for another request. Use Keep when retaining the value depends on additional logic.
You have 2 good questions about how TempData works here and here
Hope it helps!
Just finished understanding Peek and Keep and had same confusion initially. The confusion arises becauses TempData behaves differently under different condition. You can watch this video which explains the Keep and Peek with demonstration https://www.facebook.com/video.php?v=689393794478113
Tempdata helps to preserve values for a single request and CAN ALSO preserve values for the next request depending on 4 conditions”.
If we understand these 4 points you would see more clarity.Below is a diagram with all 4 conditions, read the third and fourth point which talks about Peek and Keep.
Condition 1 (Not read):- If you set a “TempData” inside your action and if you do not read it in your view then “TempData” will be persisted for the next request.
Condition 2 ( Normal Read) :- If you read the “TempData” normally like the below code it will not persist for the next request.
string str = TempData["MyData"];
Even if you are displaying it’s a normal read like the code below.
#TempData["MyData"];
Condition 3 (Read and Keep) :- If you read the “TempData” and call the “Keep” method it will be persisted.
#TempData["MyData"];
TempData.Keep("MyData");
Condition 4 ( Peek and Read) :- If you read “TempData” by using the “Peek” method it will persist for the next request.
string str = TempData.Peek("Td").ToString();
Reference :- http://www.codeproject.com/Articles/818493/MVC-Tempdata-Peek-and-Keep-confusion
TempData is also a dictionary object that stays for the time of an
HTTP Request. So, TempData can be used to maintain data between one
controller action to the other controller action.
TempData is used to check the null values each time. TempData contain
two method keep() and peek() for maintain data state from one
controller action to others.
When TempDataDictionary object is read, At the end of request marks
as deletion to current read object.
The keep() and peek() method is used to read the data without deletion
the current read object.
You can use Peek() when you always want to hold/prevent the value for
another request. You can use Keep() when prevent/hold the value
depends on additional logic.
Overloading in TempData.Peek() & TempData.Keep() as given below.
TempData.Keep() have 2 overloaded methods.
void keep() : That menace all the data not deleted on current request completion.
void keep(string key) : persist the specific item in TempData with help of name.
TempData.Peek() no overloaded methods.
object peek(string key) : return an object that contain items with specific key without making key for deletion.
Example for return type of TempData.Keep() & TempData.Peek() methods as given below.
public void Keep(string key) {
_retainedKeys.Add(key); }
public object Peek(string key) {
object value = values;
return value; }
don't they both keep a value for another request?
Yes they do, but when the first one is void, the second one returns and object:
public void Keep(string key)
{
_retainedKeys.Add(key); // just adds the key to the collection for retention
}
public object Peek(string key)
{
object value;
_data.TryGetValue(key, out value);
return value; // returns an object without marking it for deletion
}
Keep() method marks the specified key in the dictionary for retention
You can use Keep() when prevent/hold the value depends on additional logic.
when you read TempData one’s and want to hold for another request then use keep method, so TempData can available for next request as above example.

breezejs - How to initiate complex type properties when creating a new Entity

Suppose there is person type which has some complex properties such as Address and dateOfBirth
I created a new Entity of person with this code :
newPerson(manager.createEntity("Person",{ id: breeze.core.getUuid() }));
How can I initiate the complex type so I can bind it to a blank form?
In the breeze doc it says :http://www.breezejs.com/documentation/complextype-properties
This is actually slightly incorrect, you can create an ‘unbound’
instance of a complexType with the complexType.createInstance method
but when you assign it, you are simply copying its values onto an
existing instance.
Where is the best place to initiate the complex type properties?any sample code would be so helpful.
If you are dealing with a scalar navigation property, i.e. a navigation property that returns a single instance of another entity, then you can do it right in the createEntity call
newDetail = manager.createEntity("OrderDetail", { Order: parentOrder, Product: parentProduct });
If you are dealing with a nonscalar (i.e. array) navigation property then you will need to push the children into the navigation property. i.e.
newCustomer = em.createEntity("Customer");
var orders = newCustomer.getProperty("Orders");
orders.push(order1);
orders.push(order2);
// OR
// orders.push.apply(orders, ordersToPush);

Get index of object in an array

I'm building a plugin and I'm using actionscript to save the selection of an object in an illustrator document and then reference it later.
var arrObj:Array=new Array();
arrObj.push(app.activeDocument.selection[0]);
If I select now the same object in the document and check if its in the array it returns a -1 for the index value.
var id:int=arrObj.indexOf(app.activeDocument.selection[0]);
trace (id); //-1
Why is the selection not considered the same object as in that of the array?
I figured out a work around for saving the selected objects in an array and when selecting the object again in the illustrator document it would point out the index of that object in the array. Selected objects datatypes are "PathItems" and have a variable called name. All you have to do is set this variable to a value of your choice as well as saving it in an another array.
var arrObj:Array=new Array();
var nameHold:Array=new Array();
arrObj.push(document.selection[0]); // save the selection in an array
var hold:PathItem=document.selection[0];
hold.name="index1"; // setting the name variable of the selected object to a value of choice
nameHold.push(hold.name); // adding the name value in an array
Now the selected object and its corresponding name value are stored in arrays at the same index...you can compare all "PathItems" to each other by using the name variable and if the names match then you can get the index by using the .indexOf("name") method in arrays.

Update only the changed values on Entity object

how can i automatically update my entity objects changed values and save them to db.
I hava an Action like that
public ActionResult Update()
{
User userToUpdate = new User();
TryUpdateModel<User>(userToUpdate,ValueProvider);
BaseRepository.Context.AttachTo("User",userToUpdate);
BaseRepository.Context.SaveChanges();
return Json("");
}
ValuProvider : has the items that come
from the client as post data.
The problem on this code is the code update all the values but i want to update only the changed values.
How can i find the changed values on my entity object.
You should check out the ObjectContext.ApplyPropertyChanges Method
it is suppose to do what your asking for...
msdn
Two options:
On the View you could know the values that were changed by using Javascript and then you could pass that information to your controller.
You could simply compare the previous values (which you already have since you populated a view) and check each value before updating the DB.
I prefer last option, since at this point you could also check for data validation.
This is really a problem for your data access code, not anything to do with your controller. Pick an ORM that handles this for you and forget about the problem.

Resources