Reactive forms without initial view model in Vue and Vuetify - javascript

We are using forms for inserting new record or updating existing records (Update record scenerio includes view record scenerio)
Update record scenerio is easy one .
https://codepen.io/glikoz/pen/YjbeMY
But if we want to create "insert form" we don't have record, maybe we can create empty one. This resolves problem but we have to fill each property with null (Do you know any C# library for it :))
data:
{
errors:[],
name:null,
age:null,
movie:null,
city:{
id:null,
name:null
}
}
So for creating "insert form" normally we don't have a record (instance).
But if don't give record to viewModel, we are getting "cannot read property 'name' of undefined (city property is undefined)
This is natural viewmodel for insert form:
data: {
errors:[]
}
For seeing problem:
https://codepen.io/glikoz/pen/NBVOOe
I expect that v-model binding must handle this problem, is there any library, directive, approach to solve this problem?
Update (What's wrong with just creating an "instance")
I'm preparing "Insert forms" dynamically (template and data) and sending them to client side, than I'm rendering them (template and data) using this great work-> https://github.com/alexjoverm/v-runtime-template on client side.
So creating "empty" instance with each nested property is seems a little wrong.
I want to say that to component:
"You are component and I bind you with my model, If you could not find your data in my model, stop throwing exception show your default(empty) version"
I know what can I do to solve the problem in javascript -> https://medium.com/javascript-inside/safely-accessing-deeply-nested-values-in-javascript-99bf72a0855a
But I don't know Vue enough :(

Related

Meteor react design - nested component: function call

I'm currently facing a problem with Meteor and React, where i know some partly solutions but they don't work and imo none of them is pointing in the true direction.
The situation:
All is about an fitness app: I have a structure that represents exercises for customers, while each exercise can have a defined number of sets (a set is how often a exercise should be done). Each set has some properties (all the user can manipulate within the font-end).
Now i have the following component structure with some map-functions (state properties are in {}):
Training {customers,exercises,datetime,otherinfos}
- Overview {customers,exercises}
exercises.map():
- Exercise {exercise,customers}
customers.map():
- Customer {exercise,customer}
exercise.sets.map()
Set {exercise, customer, set, valuesofset}
From a UI-perspective (react) this all works without problems.
Now the idea is to have a button "Save" within the Training component. When the button is pressed, I want to save the state of all Set-Components in a "sets" collection (if it has other values than the default placeholder ones) and at the same time save the Training-Component in a "trainings" collection. But the training should also include information about what Sets are integrated (so at least the Set._id should be in the Training-Component state at time of Saving.
Here now my ideas so far:
Create refs from Training all the way down to all Sets and then, when pressing "Save" iterate over all refs and call a "Mongo.insert" from all Sets. Here i have the problem that i cannot return the inserted _id. Of course i could call a different function in each Component from Set all the way back to Training, but imo this is an overflow.
Try to manage the state of all sets within the Training state by calling a nested function. As i have onChangeHandler on the Inputs, this would always call a method in Training and check which one of the Sets was changed and then changes it. I have tried it this way, but it led to a very bad performance.
Create a temp-ID for Training, forward it to to the Sets (using the componentWillReceiveProps method) and when in Set, insert the Set in the database with the temp-ID. Then receive all Sets with temp-ID and use it to add the Training in the database. --> imo very complicated and I don't really want to do a database call if it is not necessary.
So currently i don't know how to solve this problem. The reason i try to separate "sets" and "trainings" is given through the fact, that later on i would like to give information about the last Set right next to the new empty Set whenever one is on the database. Any tips are welcome!
EDIT:
As suggested, there is also the possibility to solve the problem with Session. So therefor i have added the following code to Set:
componentDidMount() {
Tracker.autorun(() => {
Session.set(`set_${this.state.id}`, {
...this.state
});
});
}
My idea was then to iterate over all Session-Keys from Training which start with "set_" - unfortunately there is no function to that holds all Keys.
Second idea was to to use an array as value for a Session-pair. However, it's quite a procedure to handle the update of the reactive Set component (copy array from session, check whether an element is available or not, create a new one or update the existing one).
EDIT2:
I think i got a solution with Session:
Object.getOwnPropertyNames(Session.keys)
did the trick to get all SessionKeys! Thank you for your help!
If you do not want to use Redux or pass parent bound callbacks in the child component, you can try Session to store data at app level which can be accessed(set/get) in any component
https://docs.meteor.com/api/session.html
In your case, you may set values of "Set" in Session and access it in Training. You may also need https://guide.meteor.com/react.html#using-withTracker. Using withTracker will help in doing reactive update of the database on change of any Session variable.

Access property of an object of type [Model] in JQuery

So in my MVC project I have a custom Model called Survey, which contains a handful of properties. In the Survey Controller, I am saving Survey to a Session variable, so that the values of the survey's properties are persisted per session.
I want to be able to manipulate the DOM of a View based on the values of the session survey's properties. But I'm having trouble with how to access those.
I did find this relatively recent question that seems very similar but doesn't have an answer: Cannot access properties of model in javascript
Here's what I have so far: In the View I am getting the session's survey like so:
<input type="hidden" name="activeS" value="#HttpContext.Current.Session("Survey")" />
Then in the Section Scripts at the bottom I have this script to get that value and do something with it:
#Section Scripts
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
var survey = $("[name=activeS]").val();
$("[name=mddbccu][value=" + survey.mddbccu + "]").prop('checked', true);
})
</script>
End Section
If I insert "alert(survey);" after "var survey..." It does give me an alert that displays the type that the survey object is. So it looks like the survey is being retrieved fine. But if I try "alert(survey.mddbccu);" the alert simply says "undefined".
Note that the line after that ("$([name=mddbccu]...") I know works - having previously set a variable to a specific value, using that the appropriate item is checked. But in attempting to get the value of this particular property of the survey, nothing is checked.
So how do I get the values of the survey's properties here? Thank you!
Your approach would work with some hackery and workarounds but it is not in the spirit of MVC. Here is how you could accomplish it in the MVC way. Basically you move all the heavy lifting (parsing the item from the session) 0 to the controller and store the results in a ViewModel. This keeps the logic out of the view and makes for much cleaner and easier to maintain code.
If you have a ViewModel:
public ActionResult Survey()
{
SurveyViewModel model = new SurveyViewModel();
Survey surveySession = HttpContext.Current.Session("Survey") as Survey; // youll have to do extra null checks and such here
// map other properties from the survey object retrieved from the session to your viewmodel here!
model.mddbccu = surveySession.mddbccu;
model.otherProperty = surveySession.otherProperty
return View(model);
}
If you are just using the Survey object as the model inside the view then its even simpler:
public ActionResult Survey()
{
Survey model = HttpContext.Current.Session("Survey") as Survey;
return View(model);
}
Then, MVC magically selects stuff for you depending on what you have set in the controller. If you are using #RadioButtonFor(m => m.mddbccu, "three") then the radio will be selected if the value "three" was put into the property mddbccu in the controller.

SailsJS stop unwanted data entering the database

So, with sailsJS you can just put any old data into your model and put it into the database even if the item is not defined in the attributes object.
Is there any way to prevent this happening? is seems silly to try and do an if and then throw errors because there would be too many things to stop getting through.
For example I have just ran into the problem where I have a list of users and I'm displaying them through angular ng-repeat on the frontend and when I put the data to save a user it also decides that "$$hashKey": "00I" is going with them too !
So it automatically saved to the database and when I refresh and get the data again, the "$$hashKey": "00I" is coming back, and therefore causing this error
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by'
expression to specify unique keys.
Repeater: (key, user) in admins | filter:userSearch, Duplicate key: object:00I
This is coming from angular.
ps.
as far as i know, the server is using the default sails-disk
The default mode for Sails.js models is schemaless, which is probably not what you need. So, all you have to do is to add schema to your model:
module.exports = {
schema: true,
attributes: {
// Define all your attributes here...
}
};
After that all the values that are not described in the attributes will be automatically filtered out during the model saving.

How to access generateIdForRecord in Ember-Data?

I'm trying to develop an application using the Fixture Adapter with Ember-Data.
When I try and create a new object (based on a model I've defined), it won't work unless I specify the ID.
If I specify the ID and do this:
var person = SD.Person.createRecord({
id: 234,
name: "test"
});
var person.save();
I get:
Error: assertion failed: An adapter cannot assign a new id to a record
that already has an id. had id: 234 and you
tried to update it with 234. This likely happened because your server
returned data in response to a find or update that had a different id
than the one you sent.
Which makes it sound like somehow I'm updating an existing record (I'm not, there's only 2 fixtures for my Person object with ID's of 1 and 2 respectively).
Is Ember trying to save my object twice somehow?
I thought I may have to try and use generateIdForRecord to set the ID, but I can't reference that function no matter what I try.
newBooking.set('id', this.store.generateIdForRecord(this.store, newBooking));
newBooking.set('id', DS.generateIdForRecord(this.store, newBooking));
newBooking.set('id', this.generateIdForRecord(this.store, newBooking));
newBooking.set('id', generateIdForRecord(this.store, newBooking));
TypeError: this.store.generateIdForRecord is not a function
I'm using the latest releases of Ember and Ember-Data (have tried previous releases too). My model is implemented no differently to the TodoMVC tutorial in the Ember guides and in the tutorial nothing fancy needs to be done to manage ID's with the Fixture adapter so I've really no idea what's going on.
How do I create a new Person object (as per my example, just one 'name' field and persist it using Ember-Data's fixture adapter without the aforementioned errors?
In the end, my first code snippet worked fine.
For some reason, I was expecting to see the new object being persisted in the developer console. My models were being listed in a different view so I didn't realize it was actually working as intended.

Knockout JS Templates makes the UI "flash" when edited

I have a big problem with using Knockout JS. In my view model I have a field, called Method, that is actually an other view model.
This view model can be one of three different things (it is mapped to a polymorphic object in the domain model). To solve this I use templates that checks which type of Method that is selected withing the domain model and then shows the template that binds data for that type.
The function that checks the type of method looks like:
this.getTemplate = function (data) {
var method = data.original.get_Method();
if (method instanceof MyProj.MethodA)
return "methodA";
else if (method instanceof MyProj.MethodB)
return "methodB";
else if (method instanceof MyProj.MethodC)
return "methodC";
}
The markup where I bind the template looks like:
<div data-bind="template: {name: getTemplate($data), data: $data.Method}"></div>
This actually works very nice and when I change the type of method via an dropdown in the UI the domain model updates and the right template is shown. However here comes my problem. Each template contains a number of different fields that are specific for each method type. Whenever I change one of the values in the view model displayed by one of the templates the UI flashes and I think that happens because the template get selected again. This is quite irritating and looks extremly bad.
Any ideas on how to solve this problem? Any help would be greatly appreciated!
Thanks in advance
/Björn
Did you use any observable inside the getTemplate function. Updating the value of that observable makes the template rerender and you get your flash effect.
Checkout this link Part : "Note 5: Dynamically choosing which template is used".

Categories