I have an angular form which I build dynamically within my application. When I try and view the value of the form, it appears to be including FormGroups and not the actual values of the form.
Component 1:
this.intakeForm = this.fb.group({
requestor: ['', Validators.required],
requestJustification: ['']
});
Component 2:
ngOnInit() {
this.intakeForm.addControl('tasks', new FormArray([]));
}
/**
* Create a new task based on the user/tool combination
* #param user
* #param tool
*/
generateTask(user, tool) {
const control = <FormArray>this.intakeForm.controls['tasks'];
control.push(this.newTaskControl(user, tool))
}
/**
* Create a new control for this task
* #param user
* #param tool
*/
newTaskControl(user, tool) {
return this.fb.group({
User: user,
Tool: tool,
Roles: [[]]
})
}
Component 3:
someMethod(){
this.intakeForm.controls['tasks'].value[i].Roles.push(this.newRoleControl($event));
}
/**
* Create a new control for role
* #param user
* #param tool
*/
newRoleControl(role) {
return this.fb.group({
Role: role,
Action: null
})
}
All these seems to be working fine but I was under the impression that when I get the forms value intakeForm.value that I would receive a JSON object of the data.
From what I can tell in the image below though, the form value is still including the FormGroups.
Is this normal? Shouldn't the whole value be a valid JSON string and not contain the form components it self?
Related
I was trying to expand the extension which offers to see linked accounts for each user on the forum. It works in memberlist_view page and I would like to have it inside viewtopic_body.
I have a difficulty with narrowing the linked accounts to particular post id and author.
The closest I got is to have linked accounts from each user within the topic.
/** * Assign functions defined in this class to event listeners in the core * * #return array */ static public function getSubscribedEvents(): array { return array( 'core.viewtopic_modify_post_row' => 'viewtopic_linked_accounts_list',
` /**
* Show list of linked accounts in every post.
*
* #param data $event The event object
*
* #return void
*/
public function viewtopic_linked_accounts_list(data $event): void
{
// $this->template->assign_var('U_CAN_VIEW_LINKED_ACCOUNTS', $this->auth->acl_get('u_view_other_users_linked_accounts'));
foreach ($this->linking_service->get_linked_accounts($event['row']['user_id']) as $account)
{
$this->template->assign_block_vars('linked_accounts', array(
'ID' => $account['user_id'],
'USERNAME' => get_username_string('full', $account['user_id'], $account['username'], $account['user_colour']),
));
}
}`
I'm trying to get the values from two transaction body field using this code below .
/**
*#NApiVersion 2.x
*#NScriptType UserEventScript
*#param {Record} context.currentRecord
*/
define(['N/record'],
function (msg) {
function beforeSubmit(context) {
try {
var record = context.currentRecord;
var createdDate = record.getValue({
fieldId: 'createddate'
});
var dataNecessidade = record.getValue({
fieldId: 'custbodyek_data_nece_requ_po'
});
console.log(createdDate ,dataNecessidade);
}
catch(ex){
log.error(ex);
}
}
return {
beforeSubmit : beforeSubmit,
};
});
The error raised is "TypeError: Cannot call method "getValue" of undefined"
What I'm doing wrong here?
Thank you!
There is no currentRecord property on the context passed into a user event, hence the error message telling you that record is undefined. Review the docs for the beforeSubmit entry point to find the appropriate values.
On SuiteScript 2 each entry point has different parameters so you need to check those parameters on the Help or if you use an IDE like Eclipse, you will get that information when you create a new script, so for a UserEvent script and the beforeSubmit entry point, you will get something like this:
/**
* Function definition to be triggered before record is loaded.
*
* Task #5060 : calculate PO Spent Amount and Balance in realtime
*
* #param {Object} scriptContext
* #param {Record} scriptContext.newRecord - New record
* #param {Record} scriptContext.oldRecord - Old record
* #param {string} scriptContext.type - Trigger type
* #Since 2015.2
*/
and then you can see that the context parameter doesn't have a currentRecord property, instead, it has two other parameters that you can use newRecord or oldRecord so your code can be like this:
/**
*#NApiVersion 2.x
*#NScriptType UserEventScript
*#param {Record} context.currentRecord
*/
define(['N/record'],
function (msg) {
// are you aware that you are "injecting" the 'N/record' library into the 'msg' variable ???
function beforeSubmit(context) {
try {
var record = context.newRecord;
var createdDate = record.getValue({
fieldId: 'createddate'
});
var dataNecessidade = record.getValue({
fieldId: 'custbodyek_data_nece_requ_po'
});
console.log(createdDate ,dataNecessidade);
}
catch(ex){
log.error(ex);
}
}
return {
beforeSubmit : beforeSubmit,
};
});
You try to write it like this, I always use this method to get the field value.
const bfRecord= context.newRecord;
const createdDate = bfRecord.getValue('createddate');
I have two tables. users is a parent and leaves is a child table.
Every user has more than one leave requests.
users.id is primary key and leaves.userID is foreign key.
I want to get related user's record with the every leave record.
Here is users model
import bookshelf from '../config/bookshelf';
const TABLE_NAME = 'users';
/**
* User model.
*/
class User extends bookshelf.Model {
/**
* Get table name.
*/
get tableName() {
return TABLE_NAME;
}
/**
* Table has timestamps.
*/
get hasTimestamps() {
return true;
}
verifyPassword(password) {
return this.get('password') === password;
}
}
export default User;
Here is leaves model
import bookshelf from '../config/bookshelf';
const TABLE_NAME = 'leaves';
/**
* Client model.
*/
class leaves extends bookshelf.Model {
/**
* Get table name.
*/
get tableName() {
return TABLE_NAME;
}
/**
* Table has timestamps.
*/
get hasTimestamps() {
return true;
}
verifyPassword(password) {
return this.get('password') === password;
}
}
export default leaves;
It is my code to fetch the leaves records.
leaves.forge()
.fetchAll()
.then(leaves => res.json({
error: false,
data: leaves.toJSON()
})
)
.catch(err => res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
error: err
})
);
Unless absolutely necessary, I don't recommend performing such a function in your application code. What you are asking is very rudimentary in the data world, and your DBMS will be far more capable of processing such a request. No need to slow down your app with a request that should be off-loaded to the DBMS. It's what the DBMS is made for. Don't reinvent the wheel.
If your DBMS supports Views, then create a View to perform this function. You could also do this in a Stored Procedure. It is a very simple JOIN query that can be done in as few as 3 lines of SQL code. After you have the View, your app can read data from it just like any other table.
I am building a javascript Application. This application is using a plugin called jq-router. When I do something like the following, the address bar changes but the view fails to change.
$.router.onRouteBeforeChange(function(e, route, params){
firebase.auth().onAuthStateChanged(function(user){
if(!user && route.protected) {
$.router.go('landing', {}); <!-- This line calls the plugin.
}
});
});
The function in the plugin that is called above looks like the following.
/**
* Navigates to given route name & params
* #params {string} routeName
* #params {object} params
* #return {object} this
*/
s.go = function(routeName, params) {
var s = this;
paramSrv.setParams(params);
window.location = s.href(routeName, params);
return s;
};
You can access the entire plugin here: https://github.com/muzammilkm/jq-router
Again, expected result is that the view and the address bar update. Currently the only thing updating is the address bar, the view still renders.
You should be using onViewChange/onRouteChanged events & also exclude the landing route avoid circular loop. onRouteBeforeChange event is intended to notify the route is about to change, so that if any clean up operation can be done.
$.router.onViewChange(function(e, viewRoute, route, params){
firebase.auth().onAuthStateChanged(function(user){
if(!user && route.name !== "landing" && route.protected) {
$.router.go('landing', {}); <!-- This line calls the plugin.
}
});
});
Before creating an own solution I tried finding something which already suits my needs. I have got a node.js server where multiple clients / applications connect to. These clients will send log messages to the server which I would like to display in a panel.
Now there are some feature I that I need for a typical multiline textbox for logmessages:
I need to be able to append log messages as they will be send regularly via websockets
It should autoscrolldown unless the user is selecting text or scrolling up
It should be able to use colors and bold/regular
My question:
Is there already a solution for the above use case?
Can I give you my example? It used to be a textarea but I've refactored it to a div with little code changes.
Some highlights of the code, available on github
A custom function to send log messages:
/**
* Add a message to the gamelog
* #param {Object} options : allows custom output
* #param {String} options.message : the message to display
* #param {Boolean} options.isTimed : does the message has a timestamp in front of it?
* #param {Boolean} options.isError : is the message an error?
* #param {Boolean} options.isNewline : start the message on a new line
*/
addMessage: function (options) {
var instance = ns.instance,
audio = instance.audio,
audiofx = audio.settings.fx,
history = this.areaMessage.html();
// isTimed?
options.message = options.isTimed
? history + this.fieldClock.val() + ': ' + options.message
: history + options.message;
// isNewline?
if (options.isNewline) {
options.message = options.message + '<br />';
}
// message
this.areaMessage.html(options.message);
this.scrollTop(this.areaMessage);
// isError?
if (options.isError) {
audio.play(audiofx.error);
}
},
A scroll to top function:
/**
* Automatically scroll down (from the top)
* #param {Object} target : jQuery object
*/
scrollTop: function (target) {
target.scrollTop(99999);
target.scrollTop(target.scrollTop() * 12);
}
To use colored messages you should be able to use an HTML string:
log.addMessage({
message: '<span style="color: red;">[ERROR]</span> ',
isNewLine: false
});
log.addMessage({
message: 'the rest of the error message',
isNewLine: true
});
Feel free to use this idea to enroll your own custom message box.