AngularJS - How to add child objects during edit and then PUT - angularjs

I'm getting started with AngularJS with Web API and EF on the back end. I have an edit form that is populated via a GET request which returns a Boat object. One of Boat's properties is an Images array.
If the user adds images to Boat then I need records to be inserted into the database for each new image when the boat is updated. (But obviously not for images that the boat already had prior to edit.)
The current Web API function is:
public async Task<IHttpActionResult> Put(int id, Boat boat)
It seems I could either:
a) Push any newly added images to $scope.Boat.Images prior to the PUT. Then in the Web API function, loop through the received Boat.Images, check if a database record exists for that image, if no record exists add the image record to the database. This seems a bit uneconomical because I'm looping through every existing image and checking if it actually exists in the db already.
or
b) Send a separate object "newImages" with the PUT. Then I guess the Web API function would be:
public async Task<IHttpActionResult> Put(int id, Boat boat, string[] newImages)
This would have the benefit of not having to check which images already exist vs new ones. ie. Everything in newImages gets added to the database. But, is it weird from an AngularJS point of view to separate the new images from the Boat.Images collection?
Would you do a) or b) or... c) some other way?

I'll do A as it fits more the Restful approach.
Now Images could be an Array of complex object instead of Array of string, therefore you would have a property ID.
Then on the WebAPI side, you just add the Images without IDs set.
var newImages = Boat.Images.Select(x => x.Id == null);

Related

Entity Framework Core autosaves objects in Blazor

I might be not getting how some stuff work in Blazor, but here's what my issue is:
whenever I want to edit an object for example People object, I select it in #page "/people" from a table, then I'm redirected to the #page "people/edit/id". In #page "people/edit" I have an EditForm with InputText corresponding to the people model and the #bind value, everything is normal, it loads the data correctly.
The problem is when I edit some of the inputs and not save the data, just modify its values, and then go back to the #page "people", or anywhere, the object is modified.
I even put a breakpoint to watch the object being pulled from the database through Entity Framework Core, and it shows the modified version too, but checking on the database table, it does not seem to be affected.
It sounds impossible, but I tried with brand new projects, or others people projects in video tutorials, try replicating and does the same thing, so what's the deal here?
#page "/People/edit{id}"
#code {
[Parameter] public string id { get; set; }
Person person = new Person();
protected override async Task OnParametersSetAsync()
{
person = await PersonService.GetByIdAsync(id);
}
}
Firstly, if you put some object as a model for an EditForm and make some changes to it, all changes are reflected in the object immediately, but not after you click a submit.
Secondly, when you pull an object from a database it gets attached to the DbContext and stays attached, unless you detach it explicitly. When you query the entity, already attached to the context, the context does not query the database again, but gives you the attached entity. And if you have made some changes to it, you get these changes.
But those changes are not saved to database until you execute context.SaveChanges, so when you see the actual database, you see the unchanged data.
The difference with Net Core MVC is that Net Core MVC is stateless. Though you use references to the .NET objects in .cshtml files, they are used only during one query and get destroyed after the response is sent to client. When you use Blazor, you get actual .NET runtime ether on server (Blazor server) or on client (Blazor wasm), so your objects remain and preserve their state.

Swagger - Array of key-value pairs with unknown keys

I am trying to write a Swagger API document but I am having issues with one particular scenario.
I have a huge grid with id references in each (think Chess Board) and I want to send grid references that have changed and the new ID in each. So I may have a 40x40 grid and I change one of the grid squares to a different value.
I want to send to my API :
12x21 = 12345
23x11 = 87654
42x01 = 12987
23x09 = 19283
Without having to list every single grid position in swagger as a parameter, how can I represent this scenario using Swagger UI?
I would design one endpoint where you send the change to as a PUT request (or a POST request if it is a new id, it's hard to tell from the context), with the actual change as the JSON body of your request. The reference to your grid could then either be sent as query parameters or as part of the JSON body.

Cakephp 3 - Building an entity over several forms/actions

This is a design question.
I'm trying to build a booking system in cakephp3.
I've never done something like this with cake before.
I thought the best way might be to -- as the post title suggests -- build up an entity over several forms/actions.
Something like choose location -> enter customer details -> enter special requirements -> review full details and pay
So each of those stages becomes an action within my booking controller. The view for each action submits its content to the next action in the chain, and i use patch entity with the request data, and send the result to the new action's view.
I've started to wonder if this is a good way to do it. One significant problem is that the data from each of the previous actions has to be stored in hidden fields so that it can be resubmitted with the new data from the current action.
I want the data from previous actions to be visible in a read only fashion so I've used the entity that i pass to the view to fill an HTML table. That's nice and it works fine but having to also store that same data in hidden fields is not a very nice way to do it.
I hope this is making sense!
Anyway, I thought I'd post on here for some design guidance as i feel like there is probably a better way to do this. I have considered creating temporary records in the database and just passing the id but i was hoping I wouldn't have to.
Any advice here would be very much appreciated.
Cheers.
I would just store the entity in the DB and then proceed with your other views, getting data from the DB. Pseudo:
public function chooseLocation() {
$ent = new Entitiy();
patchEntity($ent,$this->request->data);
if save entity {
redirect to enterCustomerDetails($ent[id]);
}
}
public function enterCustomerDetails($id) {
$ent = $this->Modelname->get($id);
// patch, save, redirect again ...
}

Playframework forwarding json values to a form

I am new to Playframework and AngularJS and developing an application in AngularJS on the front end and Playframework on the back end.
I am facing one scenario: when the user clicks a menu link (Show students), it should show all the students. In the play action, the data is sent as json. Now the problem is if the data is sent as Json, then I don't see the option for which page it should forward to.
Alternatively, I have to use the normal playframework style like forwarding to page with list of values.
//This is the current playframework code I use. Here I set the values to students form
// This is not the way I want
public static Result getAllEmployees(){
List<Student> all = Student.find.all();
JsonNode json = Json.toJson(all);
return ok(views.html.students.render(all));
}
//This is the way I want
public static Result getAllEmployees(){
List<Student> all = Student.find.all();
JsonNode json = Json.toJson(all);
return ok(json); // no option for specifying the page.
}
Is there anyway to do it?
They are both valid approaches to returning data, but the first returns a whole html page, for example in response to a #routes.Employees.getAllEmployees reference in your view. The second one returns just a Json content type response, for example in response to a Javascript request or AngularJS $http.get. The methods need to have different names (they can't both be called getAllEmployees). Both of them will have entries in the routes file. They will be different entries the way you have written them, so perhaps something like:
GET /employee controllers.Employees.getAllEmployees
GET /api/employee controllers.Employees.apiGetAllEmployees
(Disclaimer: I haven't done this in AngularJS yet, but the principle should be similar.)

Updating list of models on the database ASP.NET MVC 5

I have a list of models that are displayed on the views. Say they are a list of Task. The list has a check button where one can check if Task is done. I want them to be updated on the database at once. How would I do that ?
Here's how my controller looks like :
public async Task<ActionResult> TaskManager(Tasks model, string id)
{
var user = await UserManager.FindByIdAsync(id);
var list = from task in context.Tasks.Where(t=> t.isAssigned == false)
select task;
foreach(var t in task)
{
t.isAssigned =(bool) // FROM EACH LIST ITEM IN THE VIEW ;
}
await context.SaveChangesAsync();
return View();
}
button where one can check if Task is done. I want them to be updated on the database at
once. How would I do that ?
You look at the wrong place. It isn not by doing "normal" MVC but by using Ajax.
User presses checkbox, a callback is made to a Api method (REST method) that does not return a HTML page but juts 200 - OK. It gets the ID as parameter and updates the task in the database. Right there, immediatly when the value changes.
Basically if you want to react to a checkbox change, you must do so - and it gets inefficient and slow to refresh the whole page then. This is why Microsoft invented many many year ago Ajax (before others even came up with the word). And it is well supported.
This is the moment you have to byte the not totally sweet apple for some of us and learn some javascript / JQuery to run in the browser. Been there last week, it is not THAT hard ;)
Entity Framework is not supporting by default Batch processing. There are few possibilities for that. See this comment:
https://stackoverflow.com/a/13024320/1164761

Resources