How to create an TextField with input history? - kotlin

How to create a TextField is explained very well in a tutorial. But I am wondering how to store and retrieve the entered strings in a persistant way, that survives application termination and restart (something like a Bash history).

I will try to give you a very briefly answer
You need
a viewmodel class
a repository class
a database (room database is ideal)
an entity data class
a dao class
You should find more info about room database from jetpack libraries.
Of course are uncounted ways to implement this feature but it is in general the following way recommended.
You capture from your view the query string, may on submit.
In viewmodel you implement a method captureSearchQuery(query: String)
Also in viewmodel you implement a method for example retrieveSearchHistory() : Flow<List>
The repository class is your single source of true, is the layer between the data layer and the view layer, you implement also this two methods you need, captureSearchQuery and retrieveSearchHistory. In repository class you can may transform your data, for example is a good practice to have a separate data model for the data you display on the view from your room entity. There you can do this transformation for exmaple.
Now you have setup your room database you can insert and get the data you need.
The data should go this way:
View -> Viewmodel -> Repository -> Room database
View <- Viewmodel <- Repository <- Room database
The layer should never communicate otherway, (clean architecture) for example:
View -> Room database.
The above is my simplest explanation, I hope I help you

Related

Where should my SQL code go in MVC

I'm just starting to learn the MVC design pattern, and I was wondering where should my SQL code go.
For example, lets say I have a register form structure that looks like this
type Form struct {
Username string
Password string
}
I assume that the form structure is part of the model, so I have some function that goes with the form that after a user submits the form, the data gets put into the database, so my function would look something like this
func (f *Form) registerUser() {
// SQL code goes here
}
Is this the best way of doing it? I have been searching around for open source Golang web apps that utilizes the MVC pattern, but I have not be able to find one which I completely understand.
In model-view-controller pattern...
Model is for entities all your classes represent real world objects.
View is the forms and all the graphic things user can see and interact with.
Controller is for controller classes, is all the logic of the program, for the sql code as you said you can implement a dao pattern and have all the sql code in the controller package and the database class in the entities package(i leave it in the Controller class).
I assume that the form structure is part of the model, so I have some function that goes with the form that after a user submits the form, the data gets put into the database, so my function would look something like this
Another use of Model in MVC application architecture is to store reusable code. So, yes, you can store the form in Model (for example, if you reuse it multiple in views) but this makes less sense than storing form in a View and reuse it later on.
The execution backtrace would be something like
Controller processes the request - personally, I do the business logic here and also (if necessary) invoke ...
Model that handles all the data retrieval from DBMS, validation, etc. and returns processed data to Controller and ...
The View is then displayed with the respective parameters (user data, template, validator result, etc.).
User fills in the form and submits the input to Controller and ...
GOTO 1. point

Passing state between view models

Just wondering really if there's a consensus on the 'right' way to do this, for MVVM, DDD, and other philosophies . . .
So I've got a login screen, represented by a ViewModel, LoginViewModel. It can take a name and password. It also takes in through dependency injection a LoginService, that implements the logic of taking the username and password, and retrieving the Employee object.
My question is what's the 'right' way to get this information to the next view model? Let's say it's AccountSettings, which needs to know about the logged in employee. How do we encapsulate that? I've got an AccountSettingsViewModel, but should it require
a) An instance of the LoginViewModel?
b) An instance of the LoginService, which keeps a reference to the logged in employee
c) A shared object or field on a global object, like App or something?
Thanks in advance!
Personally all my view models in DDD or otherwise are simple data containers, used to restrict the data that gets sent from the application to the UI/view. I might include some code in my view models that's specific to transforming data for that view. I also consider my view models to be coupled to my views (I only mention this because I've seen 2 teams put them in their own separate project/assembly away from the views!).
If I have anything copying data, or performing actions to get the data needed for the view model, this would live in either my domain model or my application layer, probably in a service. I wouldn't ever inject a service into a view model.

Using repository pattern with ORM

I have created a little project where I pass data from my controllers to a service class which uses an ORM to for example save an object:
Something like this:
The UserController receives the post data and passes it to the UserService.
The UserService creates a user object and saves it to the database with $user.save();
Now I'm struggling with two things:
First:
Let's say I use a repository to add the user, it would be like this:
Controller passes post data to the service which creates the user object and passes it to the repository. The only thing the repository has to do is call $user.save(), isn't that a bit weird? Why not calling save in my service, because using a repository just to call a save method seems overkill to me.
Second:
I read that when you use repositories, you can easily change storage methods because your application isn't aware which one is used. But before passing an object to your repository, you have to create it.
Using an ORM, each one has a different way: Doctrine uses $user = new User while Propel uses $user = new User(), idiorm uses $user = ORM::for_table('user')->create(); So when switching to another ORM for some reason comes with changing this in your project too, no?
First: Have a read about the responsibilities of Model View and Controller. There's a reasonable explanation with an example at this site: http://tomdalling.com/blog/software-design/model-view-controller-explained/
With regard to the Model and your ORM - the ORM would probably exist within the Model. So you should be asking your Model to create a new object (which may represent a single table or a series of related tables - your Model should understand these relationships). You can then pass data to your Model and your Model should then store the data into the appropriate columns in the appropriate tables. A simple example, imagine creating an object called 'Family' where you might specify 2 parent names, a variable number of children names and then tell the Model to save this. The Model may take this 'Family' object and create a single Family table record and 5 Person table records, flagging some as parents and others as children.
Second: The 'Storage Methods' referred to are (in my opinion) referring to the database you use. For example I know that Propel supports MySQL, PostgreSql, MSQL, Oracle, and others. My switch the configuration to a different database Propel will automatically start talking the appropriate language for the new database.

One view for various data from DB using repositories and UoW

I come from PHP and I really struggle with one model/one view approach when trying to display data from multiple entities in one View.
I've been learning asp.net mvc 4 with EF for about a month but still didn't find a good working solution to solve this issue.
My current approach is to access DB through Unit-Of-Work that creates Repository for every entity (table in DB)
public GenericRepository<Domain> DomainRepository
{
get
{
if (this.domainRepository == null)
{
this.domainRepository = new GenericRepository<Domain>(context);
}
return domainRepository;
}
}
then repository holds data from given entity (in this scenario DB),
public GenericRepository(PanelContext context)
{
this.context = context;
this.dbSet = context.Set<TTypeParam>();
}
and uses methods to filter data etc.
Using single repository to serve given view is not a problem because it uses only one model(entity).
When I'm trying to create model class (Combined) that holds ex. two models (Domain and Domain2) it's not a part of given context because that entity doesn't exist so it's pointless to use #model namespace.Models.Combined in a View.
Right now I'm using tuple to pull data from multiple repositories and use it to populate strongly-typed View but I know that there has to be a better way...
Basically the question is how to create an (abstract)? model class (entity)? that will hold data from multiple repositories and serve as viewmodel for a given View?
Big, big thanks for any help.
First of all the view model is not db entity. It's just a bucket used to send data to view. The controller populates that view model taking all the data required from the Model (repositories,services).
So if your view model is the Combined type, the controller will ask the repositories (which are NOT wrappers over EF, forget the examples you saw on asp.net mvc site or ef tutorials, they're wrong and teach you the repository anti-pattern) for data, wich may or may not be in the format neded by the view model. If it isn't, then create some extension methods in which you can map the objects returned by the repos to the view model.
So, the view model serves the View and it's populated by the controller with data from repositories. This way, the View is decoupled from the Model, because it knows only about the view model.

Where should the data be stored in MVVM?

I've got this Silverlight Prism application that is using MVVM. The model calls a WCF service and a list of data is returned.
The ViewModel is bound to the View, so the ViewModel should have a List property.
Were should I keep data returned by a WCF service in MVVM?
Should the List property be calling into the Model using its getter? Where the model has a ReturnListOfData() method that returns the data stored in the model.
Or does the ViewModel stores the data after the Model is done with calling the server?
This is a follow up on Where to put the calls to WCF or other webservices in MVVM?
Generally if I need to keep the Model objects around (I consider most things coming back from a WCF service a Model object) I will store it in my ViewModel in a "Model" property.
I've seen people go so far as to create a standard Model property on their base ViewModel type, like this (I don't do this, but it's nice):
public class ViewModel<ModelType> : INotifyPropertyChanged ...
{
//Model Property
public ModelType Model
{
...
}
}
It's really up to you. Keeping them as close to their related ViewModels is probably the thing to take away here.
It really depends on other aspects of your application. E.g. how's the data returned by ReturnListOfData() used? Are there other components interested in it? Does user update elements in the list? Can it create new elements that he'll want to save later? etc.
In the simplest case you'd just have a List property exposed by your viewmodel to view, and you'd reset that list to whatever ReturnListOfData() returned. It will probably work for a case when user simply performs a search, doesn't do anything to the data later on, and there's only one view that is interested in that data.
But suppose a user wants to be able to modify elements of that list. Clearly, you'll have to somehow track the changes in that original list, so then when user clicks save (or cancel), you'd send to the server only elements that were changed (or added) or restore the original elements if user clicks cancel. In this case you'd need a Model object, that would keep the original data, so then your viewmodel contains only its copy.