The code below will create a Email Activity in CRM but I can't figure out how to add multiple recipients. If I try to add a second recipient it just replaces the first recipient.
function CreateEmail() {
alert("CreateEmail Begin");
var email = new Object();
email.Subject = "Sample Email Using REST";
SDK.JScriptRESTDataOperations.Create(email, "Email", EmailCallBack, function (error) { alert(error.message); });
}
// Email Call Back function
function EmailCallBack(result)
{
var activityParty=new Object();
// Set the "party" of the ActivityParty // EntityReference of an entity this activityparty relatated to.
activityParty.PartyId = {
Id: "8384E684-7686-E011-8AF0-00155D32042E",//replace this with the contactid from your system.
LogicalName: "contact"
};
// Set the "activity" of the ActivityParty
// EntityReference.
activityParty.ActivityId = {
Id: result.ActivityId,
LogicalName: "email"
};
// Set the participation type (what role the party has on the activity).
activityParty.ParticipationTypeMask = { Value: 2 }; // 2 mean ToRecipients
SDK.JScriptRESTDataOperations.Create(activityParty, "ActivityParty",ActivityPartyCallBack , function (error) { alert(error.message); });
}
function ActivityPartyCallBack(reuslt)
{
alert("Process Completed");
}
Here’s a snippet that creates a email with multiple Recipients. The key was to set the email_activity_parties attribute so that we can pass an object.
Essentially email_activity_parties lets us submit a Array of Object instead a top level Object.
function CreateEmail() {
debugger;
var email = new Object();
email.Subject = "my email";
email.Description = "my email description";
var activityParties = new Array();
var partyObj0 = new Object();
partyObj0.PartyId = { Id: "a9568879-e61c-e411-80bb-000c29c1100f", LogicalName: "systemuser" };
partyObj0.ParticipationTypeMask = { Value: 1 };
activityParties[0] = partyObj0;
var partyObj1 = new Object();
partyObj1.PartyId = { Id: "b23f7a24-2223-e411-80c8-000c29c1100f", LogicalName: "contact" };
partyObj1.ParticipationTypeMask = { Value: 2 };
activityParties[1] = partyObj1;
var partyObj2 = new Object();
partyObj2.PartyId = { Id: "ffd09f25-1748-e411-80cb-000c29c1100f", LogicalName: "contact" };
partyObj2.ParticipationTypeMask = { Value: 2 };
activityParties[2] = partyObj2;
//set email.email_activity_parties to activityParties
email.email_activity_parties = activityParties;
SDK.REST.createRecord(email, "Email", EmailCallBack, function (error) { alert(error.message); });
}
// Email Call Back function
function EmailCallBack(result) {
debugger;
}
Dont have a REST sample I'm afraid, but in C# SOAP you have to pass a collection of entities, perhaps its the same in REST?
Entity e = new Entity("phonecall");
e["to"] = new Entity[]
{
ToActivityParty(new EntityReference("contact", contact1)),
ToActivityParty(new EntityReference("contact", contact2)),
};
static Entity ToActivityParty(EntityReference entityReference)
{
Entity party = new Entity("activityparty");
party["partyid"] = entityReference;
return party;
}
Related
I am trying to use javascript URLSearchParameters in which a user can type in certain fields to get particular data sets in json file.
The URLSearchParameter seems to work for when you select certain fields but it does not seem to parse the URL correctly in certain situations.
For Example symbol and apikey is a required field.
Optional fields are start date and end date.
When I type in symbol and apikey and leave all of the optional fields empty, the script breaks. When I type any one of the optional fields, it works. My code is provided below. My schema is not like this but below is an example that is similar. I have more optional fields in my final code but if all of them are empty my code continues to break.
Also I would like to know if there is any simpler way to write this code as I'm repeating the code in if else statements and I am repeating the code the same way.
(function() {
// Create the connector object
var myConnector = tableau.makeConnector();
// Define the schema
myConnector.getSchema = function(schemaCallback) {
var cols = [{
id: "symbol",
alias: "symbol",
dataType: tableau.dataTypeEnum.string
}, {
id: "date",
alias: "date",
dataType: tableau.dataTypeEnum.date
}
];
var tableSchema = {
id: "My data",
alias:"My daily data ",
columns: cols
};
schemaCallback([tableSchema]);
};
// Download the data
myConnector.getData = function(table, doneCallback) {
var dataObj = JSON.parse(tableau.connectionData);
const searchParams = new URLSearchParams (dataObj);
const apiCall = `https://mywebsite/getMyData.json?${searchParams}`;
$.getJSON(apiCall, function(resp) {
var feat = resp.results,
tableData = [];
// Iterate over the JSON object
for (var i = 0, len = feat.length; i < len; i++) {
tableData.push({
"symbol": feat[i].symbol,
"date": feat[i].date,
});
}
table.appendRows(tableData);
doneCallback();
});
};
tableau.registerConnector(myConnector);
// Create event listeners for when the user submits the form
$(document).ready(function() {
$("#submitButton").click(function()
{
if ($('#symbol').val().trim().length == 0 || $('#apikey').val().trim().length == 0)
{
$('#errorMsg').show().html("Symbol and APi key can't be blank.");
}
else if ($('#start-date').val().trim().length == 0){
var dataObj = {
apikey: $('#apikey').val().trim(),
symbol: $('#symbol').val().trim(),
endDate: $('#end-date').val().trim(),
}
tableau.connectionData = JSON.stringify(dataObj);
tableau.connectionName = "My Data";
tableau.submit();
}
else if ($('#end-date').val().trim().length == 0){
var dataObj = {
apikey: $('#apikey').val().trim(),
symbol: $('#symbol').val().trim(),
startDate: $('#start-date').val().trim(),
}
tableau.connectionData = JSON.stringify(dataObj);
tableau.connectionName = "My Data";
tableau.submit();
}
else if ($('#start-date').val().trim().length == 0 && $('#end-date').val().trim().length == 0){
var dataObj = {
apikey: $('#apikey').val().trim(),
symbol: $('#symbol').val().trim(),
type: $('#type').val().trim(),
}
tableau.connectionData = JSON.stringify(dataObj);
tableau.connectionName = "My Data";
tableau.submit();
}
else{
var dataObj = {
apikey: $('#apikey').val().trim(),
symbol: $('#symbol').val().trim(),
startDate: $('#start-date').val().trim(),
endDate: $('#end-date').val().trim(),
};
tableau.connectionData = JSON.stringify(dataObj);
tableau.connectionName = "My Data";
tableau.submit();
}
});
});
})();
I've been trying to crack my problem for quite some time however no matter what I do I can't figure this out. Currently, following the docs from TinyMCE, this code is provided by them.
/* This represents a database of users on the server */
var userDb = {};
userNames.map(function(fullName) {
var name = fullName.toLowerCase().replace(/ /g, '');
var description = descriptions[Math.floor(descriptions.length * Math.random())];
var image = 'https://s3.amazonaws.com/uifaces/faces/twitter/' + images[Math.floor(images.length * Math.random())] + '/128.jpg';
return {
id: name,
name: name,
fullName: fullName,
description: description,
image: image
};
}).forEach(function(user) {
userDb[user.id] = user;
});
/* This represents getting the complete list of users from the server with only basic details */
var fetchUsers = function() {
return new Promise(function(resolve, _reject) {
/* simulate a server delay */
setTimeout(function() {
var users = Object.keys(userDb).map(function(id) {
return {
id: id,
name: userDb[id].name,
};
});
resolve(users);
}, 500);
});
};
/* This represents requesting all the details of a single user from the server database */
var fetchUser = function(id) {
return new Promise(function(resolve, reject) {
/* simulate a server delay */
setTimeout(function() {
if (Object.prototype.hasOwnProperty.call(userDb, id)) {
resolve(userDb[id]);
}
reject('unknown user id "' + id + '"');
}, 300);
});
};
return {
fetchUsers: fetchUsers,
fetchUser: fetchUser
};
})();
/* These are "local" caches of the data returned from the fake server */
var usersRequest = null;
var userRequest = {};
var mentions_fetch = function(query, success) {
/* Fetch your full user list from somewhere */
if (usersRequest === null) {
usersRequest = fakeServer.fetchUsers();
}
usersRequest.then(function(users) {
/* query.term is the text the user typed after the '#' */
users = users.filter(function(user) {
return user.name.indexOf(query.term.toLowerCase()) !== -1;
});
users = users.slice(0, 10);
/* Where the user object must contain the properties `id` and `name`
but you could additionally include anything else you deem useful. */
success(users);
});
};
When I try to change the fake server to get data from my actual server through an API route, however, I get .filter is not a function error. So I figured I would use the Object. values() method, but that doesn't return anything and the console log shows up empty.
This is my logic in my controller (I'm using Laravel btw)
public function getUsers(Request $request) {
$user = User::all();
return $user;
}
The filter problem happens when I change this line :
if (usersRequest === null) {
usersRequest = fakeServer.fetchUsers();
}
To my API call like this:
if (usersRequest === null) {
usersRequest = fetch('api/users/mention');
}
My API response is as follows:
[{id: 1, name: "John", email: "john#doe.com", email_verified_at: null,…},…]
0: {id: 1, name: "John", email: "john#doe.com", email_verified_at: null,…}
1: {id: 2, name: "Admin", email: "vi#example.com", email_verified_at: "2021-02-07 12:01:18",…}
2: {id: 3, name: "Admin2", email: "di#example", email_verified_at: "2021-02-07 12:01:46",…}
Figured it out! After painstakingly trying and trying, I managed to find a solution.
Wrap the tinymce script in a function, I wrapped mine in a function called function tinyMCE()
before the function, run an ajax api call
var usergetNames = [];
$.ajax({
url: '/api/users/mention',
method: 'get',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
usergetNames = data;
tinyMCE();
},
error: function (ex) {
alert(ex.responseText);
}
});
In tinyMCE, replace var userNames line with this
var userNames = usergetNames;
You can get the rest of the code for tinymce mentions in their official documentation page.
I have made a scheduled script which is sending PDF though email.send()
I have get the filters as params from Suitelet. I want to get the name of the user (from runtime.getCurrentUser) and pass it to my PDF. I m just confused how to pass them and will that API be used in Suitelet or Sched script.
Can anyone help me with the code?
Here is my Scheduled script code:
/**
* #NApiVersion 2.x
* #NScriptType scheduledscript
*/
define(['N/ui/serverWidget', 'N/search', 'N/render', 'N/runtime', 'N/file', 'N/email'],
function (ui, search, render, runtime, file, email) {
function execute() {
try {
generateReport();
}
catch (e) {
log.error('generateReport ERROR', e);
}
}
function generateReport() {
var slfilters = runtime.getCurrentScript().getParameter({ name: 'custscript_searchfilter_report' });
log.debug('slfilters', slfilters);
if (!!slfilters) {
slfilters = JSON.parse(slfilters);
}
log.debug('slfilters2', slfilters);
var user = runtime.getCurrentUser();//Need this user to be passed to my xml template
var gender = slfilters.gender;//getting this from Suitelet
log.debug('gender', gender);
var item = slfilters.item;//getting this from Suitelet
log.debug('item', item);
var item_ = getItems(item, gender);
log.debug('getItems(item, gender)', item_);
//return item;
var xmlTemplateFile = file.load(3918);
//var template = script.getParameter({ name: 'custscript_template' });
var renderer = render.create();
renderer.templateContent = xmlTemplateFile.getContents();
var customSources = {
alias: 'searchdata',
format: render.DataSource.JSON,
data: JSON.stringify({
value: item_,
})
};
renderer.addCustomDataSource(customSources);
var xml = renderer.renderAsString();
var pdf = render.xmlToPdf({
"xmlString": xml
});
email.send({
author: 317,
recipients: 'aniswtf#gmail.com',
subject: 'Item Report',
body: 'Report Generated: ',
attachments: [pdf]
});
}
//
// ─── GET RESULTS ───────────────────────────────────────────────────
//
const getResults = function (set) {
var results = [];
var i = 0;
while (true) {
var result = set.getRange({
"start": i,
"end": i + 1000
});
if (!result) break;
results = results.concat(result);
if (result.length < 1000) break;
i += 1000;
}
return results;
};
//
// ─── GET ITEMS ───────────────────────────────────────────────────
//
function getItems(item, gender,user) {
try {
log.error('getItems Function started');
var itemSearch = search.load({
id: 'customsearch_mx_itemsearch'
});
var defaultFilters = itemSearch.filters;
itemSearch.filters.push(
search.createFilter({
name: "custitem5",
operator: 'anyof',
values: gender
}),
search.createFilter({
name: "internalid",
operator: 'anyof',
values: item
})
);
//defaultFilters = arrFilters;
//defaultFilters = defaultFilters.concat(arrFilters);
//log.error('Updated Filters', defaultFilters)
log.error('itemSearch', itemSearch);
//return defaultFilters;
var results = itemSearch.run().getRange({
start: 0,
end: 150
});
var result2 = results.map(function (x) {
// var results = getResults(itemSearch.run()).map(function (x) {
return {
'category': x.getText({
name: "custitem10",
join: "parent"
}),
'season': x.getValue({
name: "custitem11",
join: "parent"
}),
'riselabel': x.getText({
name: "custitem_itemriselabel",
join: "parent"
}),
'fit': x.getText({
name: "custitem9",
join: "parent"
}),
'name': x.getText({ //sku
name: "itemid",
join: "parent"
}),
'style': x.getText({
name: "custitem8",
join: "parent"
}),
'inseam': x.getText({
name: "custitem7",
join: "parent"
}),
'wash': x.getText({
name: "custitem_washname",
join: "parent"
}),
};
});
log.debug('Results', results.length);
log.debug('results', results);
log.debug('result2', result2);
// return results;//nabeeel's
return result2;//mine
} catch (e) {
log.error('error in getItems', e)
}
}
return {
execute: execute
};
});
There is no User in a Scheduled Script, so runtime.getCurrentUser() there will not return a value. You will need to retrieve the User via that method in the Suitelet (assuming it is not an anonymous external Suitelet).
From there you can add a Script Parameter to the Scheduled Script to hold the User, and then your Scheduled Script can read the Parameter and add the value as another Data Source on your template.
I'm trying to use ES6 Classes to construct data models (from a MySQL database) in an API that I'm building. I prefer not using an ORM/ODM library, as this will be a very basic, simple API. But, I'm struggling to get my head around how to define these models.
My data entities are (these are just some simplified examples):
CUSTOMER
Data Model
id
name
groupId
status (enum of: active, suspended, closed)
Private Methods
_getState(status) {
var state = (status == 'active' ? 'good' : 'bad');
return state;
}
Requests
I want to be able to do:
findById: Providing a single customer.id, return the data for that specific customer, i.e. SELECT * FROM customers WHERE id = ?
findByGroupId: Providing a group.id, return the data for all the customers (in an array of objects), belonging to that group, i.e. SELECT * FROM customers WHERE groupId = ?
Response Payloads
For each customer object, I want to return JSON like this:
findById(1);:
[{
"id" : 1,
"name" : "John Doe",
"groupId" : 2,
"status" : "active",
"state" : "good"
}]
findByGroupId(2);:
[{
"id" : 1,
"name" : "John Doe",
"groupId" : 2,
"status" : "active",
"state" : "good"
},
{
"id" : 4,
"name" : "Pete Smith",
"groupId" : 2,
"status" : "suspended",
"state" : "bad"
}]
GROUP
Data Model
id
title
Requests
I want to be able to do:
findById: Providing a single group.id, return the data for that specific group, i.e. SELECT * FROM groups WHERE id = ?
Response Payloads
For each group object, I want to return JSON like this:
findById(2);:
{
"id" : 2,
"title" : "This is Group 2",
"customers" : [{
"id" : 1,
"name" : "John Doe",
"groupId" : 2,
"status" : "active",
"state" : "good"
},
{
"id" : 4,
"name" : "Pete Smith",
"groupId" : 2,
"status" : "suspended",
"state" : "bad"
}]
}
Requirements:
Must use ES6 Classes
Each model in its own file (e.g. customer.js) to be exported
Questions:
My main questions are:
Where would I define the data structure, including fields that require data transformation, using the private methods (e.g. _getState())
Should the findById, findByGroupId, etc by defined within the scope of the class? Or, should these by separate methods (in the same file as the class), that would instantiate the object?
How should I deal with the case where one object is a child of the other, e.g. returning the Customer objects that belongs to a Group object as an array of objects in the Group's findById?
Where should the SQL queries that will connect to the DB be defined? In the getById, getByGroupId, etc?
UPDATE!!
This is what I came up with - (would be awesome if someone could review, and comment):
CUSTOMER Model
'use strict';
class Cust {
constructor (custData) {
this.id = custData.id;
this.name = custData.name;
this.groupId = custData.groupId;
this.status = custData.status;
this.state = this._getState(custData.status);
}
_getState(status) {
let state = (status == 'active' ? 'good' : 'bad');
return state;
}
}
exports.findById = ((id) => {
return new Promise ((resolve, reject) => {
let custData = `do the MySQL query here`;
let cust = new Cust (custData);
let Group = require(appDir + process.env.PATH_API + process.env.PATH_MODELS + 'group');
Group.findById(cust.groupId).then(
(group) => {
cust.group = group;
resolve (cust)
},
(err) => {
resolve (cust);
}
);
});
});
GROUP Model
'use strict';
class Group {
constructor (groupData) {
this.id = groupData.id;
this.title = groupData.title;
}
}
exports.findById = ((id) => {
return new Promise ((resolve, reject) => {
let groupData = `do the MySQL query here`;
if (id != 2){
reject('group - no go');
};
let group = new Group (groupData);
resolve (group);
});
});
CUSTOMER Controller (where the Customer model is instantiated)
'use strict';
var Cust = require(appDir + process.env.PATH_API + process.env.PATH_MODELS + 'cust');
class CustController {
constructor () {
}
getCust (req, res) {
Cust.findById(req.params.id).then(
(cust) => {
res(cust);
},
(err) => {
res(err);
}
)
}
}
module.exports = CustController;
This seems to be working well, and I've been able to use Class, Promise and let to make it more ES6 friendly.
So, I'd like to get some input on my approach. Also, am I using the export and required features correctly in this context?
Here is another approach,
Where would I define the data structure, including fields that require data transformation, using the private methods (e.g. _getState())
You should define those fields, relationship in your model class extending the top model. Example:
class Group extends Model {
attributes() {
return {
id: {
type: 'integer',
primary: true
},
title: {
type: 'string'
}
};
}
relationships() {
return {
'Customer': {
type: 'hasMany',
foreignKey: 'groupId'
}
};
}
}
Should the findById, findByGroupId, etc by defined within the scope of the class? Or, should these by separate methods (in the same file as the class), that would instantiate the object?
Instead of having many functions use findByAttribute(attr) in Model Example:
static findByAttribute(attr) {
return new Promise((resolve, reject) => {
var query = this._convertObjectToQueriesArray(attr);
query = query.join(" and ");
let records = `SELECT * from ${this.getResourceName()} where ${query}`;
var result = this.run(records);
// Note: Only support 'equals' and 'and' operator
if (!result) {
reject('Could not found records');
} else {
var data = [];
result.forEach(function(record) {
data.push(new this(record));
});
resolve(data);
}
});
}
/**
* Convert Object of key value to sql filters
*
* #param {Object} Ex: {id:1, name: "John"}
* #return {Array of String} ['id=1', 'name=John']
*/
static _convertObjectToQueriesArray(attrs) {
var queryArray = [];
for (var key in attrs) {
queryArray.push(key + " = " + attrs[key]);
}
return queryArray;
}
/**
* Returns table name or resource name.
*
* #return {String}
*/
static getResourceName() {
if (this.resourceName) return this.resourceName();
if (this.constructor.name == "Model") {
throw new Error("Model is not initialized");
}
return this.constructor.name.toLowerCase();
}
How should I deal with the case where one object is a child of the other, e.g. returning the Customer objects that belongs to a Group object as an array of objects in the Group's findById?
In case of relationships, you should have methods like findRelations, getRelatedRecords.
var customer1 = new Customer({ id: 1, groupId: 3});
customer1.getRelatedRecords('Group');
class Model {
...
getRelatedRecords(reln) {
var targetRelationship = this.relationships()[reln];
if (!targetRelationship) {
throw new Error("No relationship found.");
}
var primaryKey = this._getPrimaryKey();
var relatedObject = eval(reln);
var attr = {};
if (targetRelationship.type == "hasOne") {
console.log(this.values);
attr[relatedObject.prototype._getPrimaryKey()] = this.values[targetRelationship.foreignKey];
} else if (targetRelationship.type == "hasMany") {
attr[targetRelationship.foreignKey] = this.values[this._getPrimaryKey()];
}
relatedObject.findByAttribute(attr).then(function(records) {
// this.values[reln] = records;
});
}
...
}
Where should the SQL queries that will connect to the DB be defined? In the getById, getByGroupId, etc?
This one is tricky, but since you want your solution to be simple put the queries inside your find methods. Ideal scenario will be to have their own QueryBuilder Class.
Check the following full code the solution is not fully functional but you get the idea. I've also added engine variable in the model which you can use to enhance fetching mechanism. All other design ideas are upto your imagination :)
FULL CODE:
var config = {
engine: 'db' // Ex: rest, db
};
class Model {
constructor(values) {
this.values = values;
this.engine = config.engine;
}
toObj() {
var data = {};
for (var key in this.values) {
if (this.values[key] instanceof Model) {
data[key] = this.values[key].toObj();
} else if (this.values[key] instanceof Array) {
data[key] = this.values[key].map(x => x.toObj());
} else {
data[key] = this.values[key];
}
}
return data;
}
static findByAttribute(attr) {
return new Promise((resolve, reject) => {
var query = this._convertObjectToQueriesArray(attr);
query = query.join(" and ");
let records = `SELECT * from ${this.getResourceName()} where ${query}`;
var result = this.run(records);
// Note: Only support 'equals' and 'and' operator
if (!result) {
reject('Could not found records');
} else {
var data = [];
result.forEach(function(record) {
data.push(new this(record));
});
resolve(data);
}
});
}
getRelatedRecords(reln) {
var targetRelationship = this.relationships()[reln];
if (!targetRelationship) {
throw new Error("No relationship found.");
}
var primaryKey = this._getPrimaryKey();
var relatedObject = eval(reln);
var attr = {};
if (targetRelationship.type == "hasOne") {
console.log(this.values);
attr[relatedObject.prototype._getPrimaryKey()] = this.values[targetRelationship.foreignKey];
} else if (targetRelationship.type == "hasMany") {
attr[targetRelationship.foreignKey] = this.values[this._getPrimaryKey()];
}
relatedObject.findByAttribute(attr).then(function(records) {
// this.values[reln] = records;
});
}
/**
* Test function to show what queries are being ran.
*/
static run(query) {
console.log(query);
return [];
}
_getPrimaryKey() {
for (var key in this.attributes()) {
if (this.attributes()[key].primary) {
return key;
}
}
}
/**
* Convert Object of key value to sql filters
*
* #param {Object} Ex: {id:1, name: "John"}
* #return {Array of String} ['id=1', 'name=John']
*/
static _convertObjectToQueriesArray(attrs) {
var queryArray = [];
for (var key in attrs) {
queryArray.push(key + " = " + attrs[key]);
}
return queryArray;
}
/**
* Returns table name or resource name.
*
* #return {String}
*/
static getResourceName() {
if (this.resourceName) return this.resourceName();
if (this.constructor.name == "Model") {
throw new Error("Model is not initialized");
}
return this.constructor.name.toLowerCase();
}
}
class Customer extends Model {
attributes() {
return {
id: {
type: 'integer',
primary: true
},
name: {
type: 'string'
},
groupId: {
type: 'integer'
},
status: {
type: 'string'
},
state: {
type: 'string'
}
};
}
relationships() {
return {
'Group': {
type: 'hasOne',
foreignKey: 'groupId'
}
};
}
}
class Group extends Model {
attributes() {
return {
id: {
type: 'integer',
primary: true
},
title: {
type: 'string'
}
};
}
relationships() {
return {
'Customer': {
type: 'hasMany',
foreignKey: 'groupId'
}
};
}
}
var cust = new Customer({
id: 1,
groupId: 3
});
cust.getRelatedRecords('Group');
var group = new Group({
id: 3,
title: "Awesome Group"
});
group.getRelatedRecords('Customer');
var groupData = new Group({
"id": 2,
"title": "This is Group 2",
"customers": [new Customer({
"id": 1,
"name": "John Doe",
"groupId": 2,
"status": "active",
"state": "good"
}),
new Customer({
"id": 4,
"name": "Pete Smith",
"groupId": 2,
"status": "suspended",
"state": "bad"
})
]
});
console.log(groupData.toObj());
How do I construct a new instance of a defined object?
I have code similar to this but the this.User = new User(); it doesn't work.
(function () {
SomeApp = {
User: {
FirstName: '',
LastName: ''
},
Users: [],
init: function () {
this.User.FirstName = 'Joe';
this.User.LastName = 'Blogs';
//add user to list
var copiedUser = {};
$.extend(copiedUser, this.User);
this.Users.push(copiedUser);
//create new user
this.User = new User();
this.User.FirstName = 'Jane';
//add user to list
var copiedUser = {};
$.extend(copiedUser, this.User);
this.Users.push(copiedUser);
}
}
SomeApp.init();
})();
If you want to be able to create object using new, you may create a "constructor" :
function User() {
this.FirstName = '';
this.LastName = '';
}
Side note : I'd recommend you to follow best practices in naming variables. Please read this guide.