I am trying to link a json object to multiple objects.
$scope.persons = [
{"prename":"Max", "surname":"Shepherd"},
{"prename":"Sarah", "surname":"Shepherd"}
];
$scope.contracts = [
{"contract":"liability", "payment":"8.40"},
{"contract":"health", "payment":"48.12"}
];
// Save new Person
$scope.newPerson = {};
$scope.savePerson = function() {
$scope.persons.push($scope.newPerson);
$scope.newPerson = {};
}
// Save new Contract
$scope.newContract = {};
$scope.saveContract = function() {
$scope.contract.push($scope.newContract);
$scope.newContract = {};
}
How can I save a new Contract and link/nest it to 2 persons.
e.g. the liability contract should be nested to 2 persons.
The health contract should be nested only to 1 person.
But the contract should also be an own object.
The final array should propably look like this:
$scope.persons = [
{
"prename":"Max",
"surname":"Shepherd",
"contracts": {
{"contract":"liability", "payment":"8.40"}
}
},
{
"prename":"Sarah",
"surname":"Shepherd",
"contracts": {
"contract":"liability", "payment":"8.40"
"contract":"health", "payment":"48.12"
}
}
];
$scope.contracts = [
{"contract":"liability", "payment":"8.40"},
{"contract":"health", "payment":"48.12"}
];
you could add a contract id, and then link the id to each person who has the contract.
{"contract":"liability", "payment":"8.40","contractKey":"123"},
{"contract":"health", "payment":"48.12","contractKey":"321"}
$scope.persons = [
{
"prename":"Max",
"surname":"Shepherd",
"contracts": {
"123",
"321"
}
},
{
"prename":"Sarah",
"surname":"Shepherd",
"contracts": {
"123"
}
}
];
Then you would need a function to search for the correct contracts
function findContractForAllPeople(){
angular.forEach($persons,function(key,values){
angular.forEach(values,function(DataKey,val){
angular.forEach($contracts,function(contractKey,contractDetails)
if(DataKey === "contracts"){
if($scope.contracts.contractKey === val){
$scope.finalArray[prename] = {"contracts":contractDetails }
}
})
})
})
}
this will create an object that will look like this
{
Max:{
"contracts":{"contract":"liability", "payment":"8.40","contractKey":"123"},
{"contract":"health", "payment":"48.12","contractKey":"321"}}
},
Sarah:{
{"contract":"liability", "payment":"8.40","contractKey":"123"}
}
Related
I want to create a dynamic json string.
Json looks like:
{
"getHostedPaymentPageRequest": {
"merchantAuthentication": {
"name": "x345dsfg",
"transactionKey": "456tyYYUU7876"
},
"transactionRequest": {
"transactionType": "authCaptureTransaction",
"amount": "20.00",
"profile": {
"customerProfileId": "123456789"
}
}
}
}
The values in json like name, transactionKey, transactionType, amount, customerProfileId will vary for different users.
I am following this method to create json:
var getHostedPaymentPageRequest = new Object();
var merchantAuthentication = {};
merchantAuthentication.name = "x345dsfg";
merchantAuthentication.transactionKey = "456tyYYUU7876";
var transactionRequest = {};
transactionRequest.transactionType = "";
transactionRequest.amount = "20.00";
var profile = {};
profile.customerProfileId = "123456789";
transactionRequest.profile = profile;
getHostedPaymentPageRequest.merchantAuthentication = merchantAuthentication;
getHostedPaymentPageRequest.transactionRequest = transactionRequest;
getHostedPaymentPageRequest = JSON.stringify(getHostedPaymentPageRequest);
But its not giving back the right values.
How do I make a valid json in the desired format?
The provided code (if we add a console.log on getHostedPaymentPageRequest) displays the following result (which is how it should behave):
{
"merchantAuthentication": {
"name": "x345dsfg",
"transactionKey": "456tyYYUU7876"
},
"transactionRequest": {
"transactionType": "",
"amount": "20.00",
"profile": {
"customerProfileId": "123456789"
}
}
}
The only meaningful difference that I see between this and the expected result is that in your expected result the JSON starts with
{
"getHostedPaymentPageRequest": {
...
}
}
For that you have to wrap your getHostedPaymentPageRequest object in another object. So instead of doing this:
getHostedPaymentPageRequest = JSON.stringify(getHostedPaymentPageRequest);
add braces like this:
getHostedPaymentPageRequest = JSON.stringify({ getHostedPaymentPageRequest });
You can use this as a reference..
I've split the object based on what it's doing and I've obtained two separate objects: merchantAuthentication and transactionRequest. For each object I created a separate function who return an individual object, because in the future you might want to add more fields therefore it will be easier to you to know were to place them :)
function createMerchantAuthObject() {
let merchantAuth = {};
merchantAuth.name = "x345dsfg";
merchantAuth.transactionKey = "456tyYYUU7876"
return merchantAuth;
}
function createTransactionRequestObject() {
let transactionRequest = {};
transactionRequest.transactionType = "authCaptureTransaction"
transactionRequest.amount = "20.00"
transactionRequest.profile = {};
transactionRequest.profile.customerProfileId = "123456789"
return transactionRequest;
}
function getHostedPaymentPageRequest() {
let request = {}
request.getHostedPaymentPageRequest = {}
request.getHostedPaymentPageRequest.merchantAuthentication = createMerchantAuthObject();
request.getHostedPaymentPageRequest.transactionRequest = createTransactionRequestObject();
return request; // used in order to print the whole object
}
const myObject = getHostedPaymentPageRequest();
console.log(myObject);
This solved my problem:
var money=document.getElementById("amount").value;
var customerprofileid = "1926616706";
var merchantAuthentication = {};
merchantAuthentication.name = "ser555";
merchantAuthentication.transactionKey = "fgrtyujjj";
var getHostedPaymentPageRequest = {
"getHostedPaymentPageRequest": {
"merchantAuthentication": {
"name": merchantAuthentication.name,
"transactionKey": merchantAuthentication.transactionKey
},
"transactionRequest": {
"transactionType": "authCaptureTransaction",
"amount": money,
"profile": {
"customerProfileId": customerprofileid
}
},
"hostedPaymentSettings": {
"setting": [ {
"settingName": "hostedPaymentIFrameCommunicatorUrl",
"settingValue": "{\"url\": \"http://localhost:52965/IframeCommunicator.html\"}"
}]
}
}
};
getHostedPaymentPageRequest = JSON.stringify(getHostedPaymentPageRequest);
How to create single array for same key but different values in nodeJs with unique productId
but having different productImage with same productId i want productImage should be an array
and with same productId, productImages are in this productImage array.
var data = [
{
"productID":18,
"productTitle":"Watch",
"productImage":"1588148225540.jpg"
},
{
"productID":18,
"productTitle":"Watch",
"productImage":"15881482433232.jpg"
},
{
"productID":19,
"productTitle":"Shirt",
"productImage":"1588148214343.jpg"
}
]
My expected output should be:
[
{
"productID":18,
"productTitle":"Watch",
"productImage":[
"1588148225540.jpg",
"15881482433232.jpg"
]
},
{
"productID":19,
"productTitle":"Shirt",
"productImage":[
"1588148214343.jpg"
]
}
]
You can use uniqBy function from lodash library
const result = _.uniqBy(products, 'productID');
Here is an answer
var data = [
{
"productID":18,
"productTitle":"Watch",
"productImage":"1588148225540.jpg"
},
{
"productID":18,
"productTitle":"Watch",
"productImage":"15881482433232.jpg"
},
{
"productID":19,
"productTitle":"Shirt",
"productImage":"1588148214343.jpg"
}
]
let output =[];
data.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.productID == item.productID;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].productImage =
output[existingIndex].productImage.concat(item.productImage);
} else {
if (typeof item.productImage == 'string')
item.productImage = item.productImage;
item.productThumbImage = [item.productThumbImage];
output.push(item);
}
});
I have data in this format. This is gamesparks data that is BaaS using for game development.
I am sending this data to the IOS person but he said he can not fetch this type of data so he told me to change the data
This is my actual data
{
"Details": [{
"5d4c2c28dcf224127a30457b": {
"displayName": "ewqeqw"
},
"5d4c4699dcf224127a3045e0": {
"displayName": "mmmmmmmmmm"
}
}]
}
and I need to change data in this format
{
"Details": [{
"ID": "5d499b0fdcf224127a303d61",
"displayName": "qweqewq"
},
{
"ID": "5d499b0fdcf224127a303d61",
"displayName": "qweqewq"
}
]
}
This is my code:
var group = Spark.getData().group;
var API = Spark.getGameDataService();
var all1 = new Array();
var entry = API.getItem("playerFriends", Spark.getPlayer().getPlayerId());
var friendsList = {};
if (entry.error()) {
Spark.setScriptError("ERROR", error);
Spark.exit();
} else {
var data = entry.document().getData();
if (group === "all") {
for (var friendOBJ in data) {
//Set details of player ID and display name in new friendsList
object
friendsList[friendOBJ] = {};
friendsList[friendOBJ].displayName = data[friendOBJ].displayName;
friendsList[friendOBJ].playerId = data[friendOBJ].playerId;
}
all1.push(friendsList);
} else {
for (var friendOBJ in data) {
if (data[friendOBJ].group === group && data[friendOBJ].status ===
"accepted") {
friendsList[friendOBJ] = {};
friendsList[friendOBJ].displayName = data[friendOBJ].displayName;
}
}
}
Spark.setScriptData("Details", all1);
Can you not just make a function to convert the data into the desired shape? Something like this should work:
function formatData(details) {
var formattedDetails = [];
for (var id in details) {
formattedDetails.push({
ID: id,
displayName: details[id].displayName
});
}
return formattedDetails;
}
var data = {
"Details": [
{
"5d4c2c28dcf224127a30457b": {
"displayName": "ewqeqw"
},
"5d4c4699dcf224127a3045e0": {
"displayName": "mmmmmmmmmm"
}
}
]
};
var formattedData = formatData(data.Details[0])
this is the output you want
{
"Details": [{
"ID": "5d499b0fdcf224127a303d61",
"displayName": "qweqewq"
}
}
and this is my code i am explaining each line with comment
var count = 0;
var tmp = { AcceptedFriendList: []}; //make object and inside empty array
for (var friendOBJ in data) { // retrieving data
if(data[friendOBJ].status === "accepted"){ // your condition
var tempObj = {"displayName" :"","playerid": ""}; //this is format you want
tempObj.displayName = data[friendOBJ].displayName; // putting data in spicify format object
tempObj.playerid = data[friendOBJ].ID;
tmp.AcceptedFriendList[count] = tempObj; //assign object back to array
count++; // iterate it so the next data come further.
}}
I want to create new array by json data But I have no idea to create Object!
for show to page(loop for)
my json data
"LIBRARIES":{
"LIBRARY":[
{
"status":"available",
"callNumber":"123456"
},
{
"status":"available",
"callNumber":"434356"
}
]
}
and
"search":{
"lsr02":[
"31011103618567",
"31011001644160"
]}
I want to create object to store this data
I want
"NEWDATA":{
"NEW":[
{
"status":"available",
"callNumber":"123456",
"lsr02": "31011103618567" ///set lsr02 to store in NEW
},
{
"status":"available",
"callNumber":"434356"
"lsr02":"31011001644160"
}
]
}
and I try
let details: string[] = [];
for (let x of this.item.LIBRARIES.LIBRARY){
details.push(x);
}
for (let x of this.item.search.lsr02){
details.push(x);
}
console.log(details)
console.log(details) show
{
"status":"available",
"callNumber":"123456"
},
{
"status":"available",
"callNumber":"434356"
}
{
"31011103618567"
},
{
"31011001644160"
}
thanks for your help :)
You are pushing the search objects separately. You need to assign them to appropriate library object. Try this;
this.item = {
"LIBRARIES": {
"LIBRARY": [{
"status": "available",
"callNumber": "123456"
},
{
"status": "available",
"callNumber": "434356"
}
]
},
"search": {
"lsr02": [
"31011103618567",
"31011001644160"
]
}
}
let details = [];
for (let i = 0; i < this.item.LIBRARIES.LIBRARY.length; i++) {
let lib = this.item.LIBRARIES.LIBRARY[i];
lib.lsr02 = this.item.search.lsr02[i]
details.push(lib);
}
console.log(details)
export class NEWDATA {
public status:string;
public callNumber:string;
public lsr02 : string;
constractor(_status : string, _callNumber : string, _lsr02 : string){
this.status = _status;
this.callNumber = _callNumber;
this.lsr02 = _lsr02;
}
}
details : Array<NEWDATA> = [];
for (let i = 0; i < this.item.LIBRARIES.LIBRARY.length; i++) {
details.push(new NEWDATA(this.item.LIBRARIES.LIBRARY[i].status, this.item.LIBRARIES.LIBRARY[i].callNumber, this.item.search.lsr02[i]));
}
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());