formGroup inside another formGroup programatically without using formArray - angular-reactive-forms

I trying to add formGroup dynamically inside another formGroup without using formArray. And also add formControl in newly added formGroup dynamically.
I have also tried addFormGroup() function but its giving error that this.form.addFormGroup is not a function.

Is this what you are trying to achieve?
const f = new FormGroup({});
const userGroup = new FormGroup({});
f.addControl('user', userGroup);
userGroup.addControl('firstName', new FormControl('Vladimir'));
userGroup.addControl('lastName', new FormControl('Prudnikov'));
console.log(f.value);

Related

Load function from support folder cypress

In my support folder I have a folder called action. In there is a file calles login-action.js. The code in this file looks like this:
class LoginActions{
login(usernameField, passwordField, username, password) {
cy.get(usernameField).first().type(username);
cy.get(passwordField).last().type(password);
}
}
export default new LoginActions();
Now I want to use this login function in a test
loginActions.login('[data-test=username]', '[data-test=password]', this.user.username, this.user.password);
This is how I call it in the test. But somehow this is not working. It says that login is undefined.
I don't think that you can export new object like you are doing, I usually export only the class like this:
export default LoginActions();
Do you import and create new object loginActions like this:
import LoginActions from '../../../support/pageObjects/{loginActionsPage}'
const loginActions = new LoginActions();
And after this you can:
loginActions.login('[data-test=username]', '[data-test=password]', this.user.username, this.user.password);

Laravel 5.8 + Vue2JS Session and Old values in component

I have question about normal laravel multi form with post action as method based on laravel session. I added in this form component of vue, which is simple city autocomplete. I want load to inputs into fields of this component from session (session()), or old (old()) values, if session exist i want to load from session city and province, but if session doesnt exist, but old laravel values exist I want to load them in this component form, if they doesnt exist, leave fields empty. What's the easiest way to do that?
Get the session and pass a default which would be the old value.
$data = session('session_data_key', $old_value); // however you get the old value is up to you.
Pass it down to your view. If no session is set on the server, it will use the default (if default is null it will not set the auto-complete).
UPDATE
If you are using axios to make calls to a laravel app, before loading the form component (in mounted() {}) do a call to axios to get the value of (session or old value). This is what you'll load into the form.
axios.get('/api/load_dafault').then(resp => {
this.defaultValueToBePassedToField = resp.data.value;
});
The endpoint '/api/load_dafault' or whatever yours is named, will have it's controller like so:
public function loadDefaults()
{
$old_value = ... // however you get it is up to you.
$data = session('session_data_key', $old_value);
}
Do not forget to ensure you set the routes.

Apply MVC pattern in ES6 for invoking methods

I am using the Model-View-Controller framework to structure my files for readable, reusable, and refactorable purposes.
My goal is to invoke methods from two seperate classes while working with one class. In practice; I want to access the methods for example in file Model.js and View.js from Controller.js.
Previously in ES5 I've had one file called app.js that used the IIFE approach:
var View = (function(){
dump(){
console.log('Hello World');
}
});
var Model = (function(){
// Code goes here
});
var Controller = (function(viewCtrl, viewCtrl){
viewCtrl.dump(); // Invoke method from View
})(View, Model);
As shown above, I would like to do something similar in ES6 too.
import View from './View';
import Model from './Model';
class Controller {
dump(){
return viewCtrl.dump();
}
init(){
console.log('Application has started');
// Make a new object of the class { View, Model }
let view = new View();
let model = new Model();
}
}
export default Controller;
In my main.js:
import Controller from './Controller';
// Make a new object of the class Controller
let controller = new Controller();
// Instantiate App
controller.init();
console.log(
controller.dump()
);
But doing so in ES6 I get error: ReferenceError: viewCtrl is not defined in main.js.
I was thinking perhaps pass View.js and Model.js as arguments in a constructor inside the Controller.js in order to declare them. But I guess it might be a better solution that looks cleaner.
So what I am basically looking for is to apply the MVC pattern using ES6, any recommendations?
Passing the instances of View and Model to the constructor of Controller is a clean solution since this would fullfill the dependency-injection-pattern.
This way you get the ability to change the instances from outside which makes the Controller testable.
In a situation where View and Model where singletons you could export them as instances instead of classes like
View.js:
export default new View();
Controller.js:
import view from "./View";
...
view.dump()
Using this way you could spare the work of passing a model and a view to a Controller manually but that would also mean that you loose the ability to test Controller or to change parts of it, like the View. Since this is one of the best advantages of the MVC-pattern, I would not recommend to import singletons. Instead I would recommend to inject View and Model using a constructor.

namespacing with js prototype framework

When you create a class in the name space of example.
em.components.grid
em.components.grid.Popup = Class.create(
{
initialize: function(params){
...
},
show:function(){
// create or show
}
});
Does this mean in other classes I have access to the show method if I use the namespace path above.
// Another class in prototype
em.components.grid.Popup.show();
Or does your new class your trying to access show from have to be in the same namespace.
Is namespacing kind of like packages in other languages. So by giving a namespace you can keep all your classes related to for example grid in one name space and possible other classes unrelated to grid in another namespace.
Update
This raises 2 other questions, lets say i create my class like above with the same namespace. Then in another js document I instantiate the class
var popup = new em.components.grid.Popup()
Then popup would be a global variable not? which I don't want to have in my files if possible. Seen as I have went to all the trouble of giving it a unique name space. To then create an instance of the class on a global variable somewhere else in a js file.
So in the case of a popup is it best to have it global or would it be best to create it on a rollover event and remove it on a rollout event.
//pseudo code
$$('domelementClass').observe('mouseover', function(event) {
var popup= new em.components.grid.Popup(event.target);
})
the issue I see with above is I have no reference to remove it on the rollout.
$$('domelementClass').observe('mouseout', function(event) {
popup.remove();
})
Namespacing has the same purpose of packaging, avoiding collision. As your example above shows, in JavaScript, you namespace functions and variables by making them properties of an object.
Does this mean in other classes I have access to the show method if I
use the namespace path above.
// Another class in prototype em.components.grid.Popup.show();
In this case no because 'show()' is an instance method, it can only be called once you have a new Popup. You can use your namespaced Popup as an instance in another class or if you want to call show like a static method in Java then you would call Popup.prototype.show();
var Popup = Class.create({
initialize: function(params){
alert("I exist");
},
show:function(){
alert("show!");
}
});
// Popup.show(); // would error:
// Uncaught TypeError: Object function klass() {
// this.initialize.apply(this, arguments);
// } has no method 'show'
Popup.prototype.show();
foo = new Popup();
foo.show();
Some useful links:
http://michaux.ca/articles/javascript-namespacing
http://blog.anselmbradford.com/2009/04/09/object-oriented-javascript-tip-creating-static-methods-instance-methods/

Extjs 4 MVC loading a view from controller

Ok so I have a controller with a method in which I want to load a view.
How do I load a view from a controller?
How do I pass some parameters from the controller to the view when I load it?
Any help is much appreciated.
To load a view, you can use Ext.widget(). Use Ext.define() to create a view in your view file. I would recommend using the alias property to define an inline xtype for the view.
When you need to load the view, you create an view using Ext.widget() and specify the xtype (alias for your view). Here is an example:
// define a window
Ext.define('MyApp.view.user.Add',
extend: 'Ext.window.Window',
alias : 'widget.adduser',
.
. // Add other properties, custom properties, methods, event handlers etc..
});
Now, when you want to create an instance in your user controller, you do:
// create an instance
var view = Ext.widget('adduser'); // refer the below note!
Note: note that there is no 'widget.'! it automatically gets added to the widget name you pass.
Now, taking about passing parameters. Like Ext.create method, you should be able to pass any parameters as:
// create an instance with params
var view = Ext.widget('adduser', {title: 'New User title'});
Regarding ref: refs help you in getting references to Views on your page. They do not help in creating an instance or load a view. If you have your view rendered, you can make use of the ref system to get hold of that instance and manipulate the view. You need to make use of the ComponentQuery to get reference of your view.
refs can be used to create new instances as well as access existing ones. By adding the option autoCreate: true to your ref, a call to the getter will result in a new instance being created using the ref definition as its config if no existing component matches the selector.
refs: [{
ref: 'list'
,selector: 'myusersgrid#users'
,autoCreate: true
// any additional options get passed as config when an instance needs to be created
,xtype: 'myusersgrid'
,itemId: 'users'
,store: 'Users'
,title: 'Users'
},{
ref: 'otherList'
,selector: 'myusersgrid#administrators'
,autoCreate: true
// any additional options get passed as config when an instance needs to be created
,xtype: 'myusersgrid'
,itemId: 'administrators'
,store: 'SpecialUsers'
,title: 'Special Users'
}],
Notice the use of the # to additionally match the itemId so I could have refs to multiple instances of the same xtype
There's also a forceCreate: true option which will make the ref's getter always return a new instance, without it autoCreate will create one instance the first time it's retrieved and then keep returning the same one.
If I understand your question I think you want to use refs, take a look at the docs for Ext.app.Controller: http://dev.sencha.com/deploy/ext-4.0.0/docs/api/Ext.app.Controller.html
Basically you create a list of refs using css selectors:
refs: [
{
ref: 'list',
selector: 'grid'
}
],
Then later in the class you can access this ref by using get, i.e.:
refreshGrid: function() {
this.getList().store.load();
}
The getList() method is created for you when you create the ref to 'list'.
I ran into this same problem. I created a method on my abstract base controller to retrieve the view instance and create on if it does not exist.
This will work properly even after the view has been destroyed - a new one will be created.
Ext.define('My.controller.Base', {
extend: 'Ext.app.Controller',
//Retrieves an instance of the top-level view
//If it has not been created yet than one is instantiated
//Also, overrides the .close() method on the view to
//null out the instance reference on the controller (very necessary)
getViewInstance: function () {
var self = this;
if(!this.viewInstance) {
if(this.views && this.views.length) {
var view = this.getView(this.views[0]);
this.viewInstance = view.create();
this.viewInstance.close = function () {
view.prototype.close.apply(this, arguments);
self.viewInstance = null;
};
}
}
return this.viewInstance;
}
});
Now all my controllers can easily access their view from w/i controller code w/o any external variables.
Use Ext.create('Proper File Name to be opened',param1 = me);
In the newly created view, use this.param1 to access the parameters.
EG: Ext.create('view.HelloOverlay, param1 = "Hello", param2 = "World");
in the controller of HelloOverlay, using this.param1 will give "Hello" and this.param2 will give "World".
Sometimes the parameters passed will be present in the view so use this.getView().paramName

Resources