Insert objects without matching column name - javascript

This is probably a silly question, but I am new to node and postgresql, so I am struggling.
I am trying to use pgp.helpers.insert to insert multiple objects into the database, as the example bellow:
users = [{mycolumn:{name: 'John', age:23}}, {mycolumn:{name: 'Mike', age: 30}}];
query = pgp.helpers.insert(users, ['mycolumn:json'], 'mytable');
// insert into "mytable"("mycolumn") values('{"name":"John","age":23}'),('{"name":"Mike","age":30}')
The code above inserts into mytable 2 rows with mycolumn as a jsonb.
But I am trying to insert straight into mycolumn the values inside an array of objects, without wrapping my original object, such as:
users = [{name: 'John', age:23}, {name: 'Mike', age: 30}];
query = pgp.helpers.insert(users, ['mycolumn:json'], 'mytable');
// Error: Property 'mycolumn' doesn't exist.
Of course it doesn't work, since the object doesn't contain a mycolumn attribute. But I think it is not elegant to iterate in my array wrapping the original object with the column name, specially since I am working with millions of rows (working in batches, of course).
Thanks in advance.

You can use the following definition for your column, as per the Column syntax:
{
name: 'mycolumn',
init: c => c.source // use the source object itself
}
i.e.
const cs = new pgp.helpers.ColumnSet([
{
name: 'mycolumn',
init: c => c.source
}
], {table: 'mytable'});
and then use it:
const query = pgp.helpers.insert(users, cs);
Note that we are not specifying the modifier - mod: ':json', because we are returning an object from init, and objects are formatted as JSON by default.

Related

How can I add the data of one JS object to another

In the function there is an empty JS object
var globalDataObject = [{}];
Then, there is a loop that goes over an array of users, stores the properties of each user in variables (ex. name, lastName, ...) and creates an object for each user:
//create an object containing the current name
const currentObject = {
'profile': {
'name': nameVariable,
'lastName': lastNameVariable
}
};
What is the right way to add the data of currentObject to the globalDataObject once it's created? So that at the end the globalDataObject should be:
var globalDataObject = [
'profile': {
'name': 'John',
'lastName': 'Smith'
},
'profile': {
'name': 'Ann',
'lastName': 'Lee'
},
'profile': {
'name': 'Dan',
'lastName': 'Brown'
}
];
Important thing is that globalDataObject must be the JS object of the specified format (not the object containing multiple objects and not the array) since once it's created it is going to be converted into XML.
You can create your global object like an array:
globalDataObject = [];
And then just push in it:
globalDataObject.push(currentObject);
I dont understand the end goal of the question and why you dont just use .push() as suggested before. You havent accepted that answer so i assume its not the end goal.
globalDataObject must be the JS object of the specified format (not
the object containing multiple object and not the array)
1) The format you gave is not valid JavaScript.
2) Why cant you have an array of objects or object with nexted objects and covert that into xml
3) Why do you want to convert json into xml in the first place.
I'll take a wild guess and assume you mis-typed the globalDataObject as array, and meant it to be an object with multiple 'profile' keys. Neither is valid javascript.
Since you can't have multiple keys with same name and expect them to have different values, I propose you to use unique "indexes" for each profile.( like an array...but an object).
// init the object
const userProfiles = {};
// then later add to it like this.
let profile1 = {name: "john", lastname: "smith"};
let profile2 = {name: "alice", lastname: "wonderland"};
userProfiles[1] = profile1;
userProfiles[2] = profile2;
// you can then torn it into an array of user profile objects like this
Object.keys(userProfiles).map((index) => {return userProfiles[index];})

How to add new elements to an array without overwriting the first one?

I'm trying to add new elements to an Array but it keeps overwriting it the first element, i'm not sure if i'm doing it correctly, but this is my code:
//name and age contains value from a NgModel
this.data = [
{ "name": this.name, "age": this.age },
];
//Adds them to a new array
this.nArray = [];
this.nArray.push(this.data);
Use concat when you want to merge two arrays.
const nArray = [];
const arr = nArray.concat(this.data);
You can now use the new merged array for your purpose
As it is, you are pushing an array to an empty array. So, there is nothing like overriding here. However, assuming this.nArray is filled with some elements already, you should use the spread syntax for concatenating two arrays like:
this.nArray.push(...this.data);
push method is ok for you. It will add elements at the end of the array. If you have data already setted in your array, then remove this.nArray = [] because this is creating a new empty array, deleting all previous data stored in nArray variable. In any case, if you want to add elements at the beginning try unshift: this.nArray.unshift(this.data);.
If you push data inside nArray you will get an array of array of objects. Maybe you are looking to add only the elements in data and not the whole array. Use concat method for that.
this.nArray.push(this.nArray.concat(data));
Or a shorten syntax using spread operator ...:
this.nArray.push(...data);
NOTE:
I'd recommend you to use const for your array definition and remove the blank assignment of [] in nArray. Also, instead of using concat, use the spread operators with the push method.
Another way to add/insert an element into an array is to use the .splice() method.
With .splice() you can insert a new element at any given index, either overwriting what is currently in that index number, or inserting within, with no overwriting.
Example:
let secretMessage = [ 'Programming', 'is', 'not', 'about', 'what', 'you', 'get',
'easily', 'the', 'first', 'time,', 'it', 'is', 'about', 'what', 'you', 'can',
'figure', 'out.', '-2015,', 'Chris', 'Pine,', 'Learn', 'to', 'Program' ]
read: 'Programming is not about what you get easily the first time, it is about what you can figure out. -2015, Chris Pine, Learn to Program'
secretMessage.splice(6, 5, 'know,');
console.log(secretMessage.join(' '); //log array elements to console, but join them
//with a space (makes it more human legible)
read: 'Programming is not about what you know, it is about what you can figure out. -2015, Chris Pine, Learn to Program'
In this example, at index (position) 6 (starting from 0) we replace the 5 elements from index 6 with the third argument - 'know,'.
If you wanted to insert an element without replacing another, use the same .splice() method but for the second argument, type 0.
Example:
let favDrink = ['I', 'like', 'milkshake.']
favDrink.splice(2, 0, 'banana'); //at index position 2, insert 'banana'.
//***Does not replace 'milkshake'***
console.log(favDrink.join(' ');
read: 'I like banana milkshake.'
Source:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
You know what? You might be reinitializing your array every time.
Try something like this:
// create your new array
this.nArray = [];
// other code
// loop, etc
$.each(row, function(index, data) {
this.data = [
{ "name": this.name, "age": this.age },
];
// now add this element to your array:
this.nArray.push(this.data);
};
Adding the Object in the array...!
Write in this format
let data = [];
data[data.length] = {name:"Aarti",age:22}
data[data.length] = {name:"Saurav",age:23}
console.log(data);

filter an array of objects based on key/value and remove it from array

In the following function I push and object to the accountsToDelete array, I need to then remove the matching object from the accountsToAdd array. I am guessing I would have to use a combination of IndexOf, Filter, Reduce but I am still a little rough in understanding how to accomplish this. This is the current function:
accountDelete(id, name) {
const accountsToAdd = this.userForm.value.accountsToAdd;
const accountsToDelete = this.userForm.value.accountsToDelete;
this.userForm.value.accountsToDelete.push(
{
id: id,
name: name
}
);
}
You can simply use the filter function. By this you can say, that in the accountToAdd all entries should be filtered, which id fits the to deleted account.
An example:
// Initialize both lists.
let accountsToAdd = []
let accountsToDelete = []
// Preparation by adding a account to the first list.
const account = { id: 1, name: 'Max' }
accountsToAdd.push(account)
// Mark account to be removed.
accountsToDelete.push(account)
accountsToAdd = accountsToAdd.filter(acc => acc.id !== account.id)
// Verify result.
console.log(accountsToAdd)
console.log(accountsToDelete)
Note:
Your both lists are defined as constant. By this you can't use the reassignment.

How to convert data to string

I have data for example like this:
data: [{
tag: 'Apple',
}, {
tag: 'Microsoft',
}, {
tag: 'Google',
}]
And I want to convert them into like this:
data: ['Apple','Microsoft','Google']
Is there a best way to do this? Wherever I am reading, people are using complex logic using loops. So are there alternative methods to doing this?
One way is to use Array.map and replace the object ele.tag with just the value return ele.tag:
var data =
[{
tag: 'Apple',
}, {
tag: 'Microsoft',
}, {
tag: 'Google',
}];
data = data.map(function(ele){ return ele.tag; });
console.log(data);
Or in ES6 you can simply this even more:
data = data.map(ele => ele.tag);
You could use a for-in loop and push the attribute of the object into an array.
var data = [{
tag: 'Apple',
}, {
tag: 'Microsoft',
}, {
tag: 'Google',
}];
var tags = [];
for (prop in data) {
tags.push(data[prop].tag);
}
console.log(tags);
For easier handling let's take the object in the OP's code and assign it to a variable, as follows:
var obj = {"data":[{"tag":'Apple'},{"tag":'Microsoft'},{"tag":'Google'}]};
var {data}= obj; // object destructing ...
var mapped = data.map(function( e ){ return e.tag});
// re-assigning value of object's data property
obj["data"] = mapped;
console.log(obj); // obj.data now pertains to array of strings
The problem described by the OP involves an object whose data property refers to an array of objects, each with a tag property. The OP inquires as to how to revise the data property so that it refers instead to an array of string values corresponding to each object's tag property.
This example makes use of destructuring to access the array of objects. Then, it uses the array's map() method to access every element's tag property and thereby obtain its string value. The beauty of map() is that it performs iteration behind the scenes sparing the user from having to hand-code a loop with the correct logic -- although in functional programming languages instead of using iteration, recursion is more apt to be utilized for this purpose. Finally, the value of the object's data property is reset to contain the specified array of strings.

concatenate fields in JS multidim Array, sort, then create different type of JS object array

I want to take an array that looks like the following:
var contacts = [
{account: 'Acme', firstName: 'John', lastName: 'Snow'},
{account: 'Metal Industries', firstName: 'Ted', lastName: 'Smith'}
];
Note: contacts can have the same account name.
and create a function to convert the data to something that instead is an object with the following structure that's like a map where the key is account name and value is an array of alphabetized full names as below:
var acctContactObject = {
'Acme': ['John Snow','Kyle Johnson','Sara Butler'],
'HiTech Corp': ['Arnold Williams','Jason Fernandez','Sam Johnson']
};
I'm not certain that I'm taking the correct approach and wanted to seek some sage advice before proceeding. Here's what I've written so far and "psuedocode" for where I'm heading.
function convertAccountArrayToObject(contacts){
this.account = contacts.account;
this.firstName = contacts.firstName;
this.lastName = contacts.lastName;
this.sort(function(a, b) {
return a.account.localeCompare(b.account);
});
var aco = new acctContactObject();
var name;
var nameArray = [];
for(var member of this){
//this is where I get stuck
//I could create a new array to hold the account with full name
//but somehow need to add them to an array that I can sort on
//
//assuming I used an intermediate array...
//create new acctContactObject
//For acct in intermediate array
//add name to another single array and sort alphabetically
//put acct name and sorted list of names into new object
//after end of loop, return object
I've been searching to see if there's a way to do a secondary sort on a multidimensional array, but didn't find what I was looking for. I've also run across mention of "merging" properties, but am not certain if that would allow me to concatenate the values for the first and last names properly.
I don't do a lot of JS, at least not of this kind, so would appreciate knowing if I'm on the right track. Any suggestions or guidance towards a cleaner way to approach this would be appreciated.
The simplest way to do it will be as follows.
Note:I have modified contacts to include the case of same account names.
var contacts = [
{account: 'Acme', firstName: 'John', lastName: 'Snow'},
{account: 'Metal Industries', firstName: 'Ted', lastName: 'Smith'},
{account: 'Metal Industries', firstName: 'Bolt', lastName: 'Coder'}
];
function convertAccountArrayToObject(contacts){
var returnObj={},key;
contacts.forEach(function(v,i){
key=v.account;
if(!returnObj[key]){
returnObj[key]=[];
}
returnObj[key].push(v.firstName+" "+v.lastName);
});
return returnObj;
}
acctContactObject=convertAccountArrayToObject(contacts);
Upvote if you find this helpful.

Categories

Resources