Immutable JS: Set value of map inside map - immutable.js

I have Immutable like this
Immutable.Map({
name: action.data.name,
avatarUrl: action.data.up,
profileUrl: action.data.upl,
id: action.data.uid,
role: Immutable.fromJS(action.data.r),
color: Immutable.Map({
initial: '#00FF00',
})
});
All I want is to check if a value corresponding to a key exists inside color map, then change it. If it does not exist then add a new key inside color map with the new value like this:
Immutable.Map({
name: action.data.name,
avatarUrl: action.data.up,
profileUrl: action.data.upl,
id: action.data.uid,
role: Immutable.fromJS(action.data.r),
color: Immutable.Map({
initial: '#00FF00',
c-0: '#000000',
7: '#0000FF'
})
});
What I tried is this, but it aint working and adds keys anywhere.
return state.setIn(state.getIn('color', action.thread_id), action.code);
thread_id is the key like 'c-0' or '7' and code contains the value to be added or updated against the key
Update 1
When adding keys like 'c-0' and 'c-1', and '7' and '8', it adds inside the map like
Immutable.Map({
name: action.data.name,
avatarUrl: action.data.up,
profileUrl: action.data.upl,
id: action.data.uid,
role: Immutable.fromJS(action.data.r),
c: Immutable.Map({
-: Immutable.Map({
0: '#00F0F0',
1: '#0000F0',
})
})
7: '#FFFF00',
8: '#00FFFF',
color: Immutable.Map({
initial: '#00FF00'
})
});

This works for me: return state.setIn(['color', action.thread_id], action.code);

Related

Dynamic table component that automatically list each property value of the current Object data iteration (ngFor directive);

Going to the point, I'm creating a table component that receives an Object containing all information that the dynamic table needs, including head information and so on. My mission is to make it possible for every row (data), my table doesn't need to know the property name, only list its value straight away.
I did some console tests and it seems to work around those lines:
const dataList = [
{ name: 'Eugene', age: 20, alive: true },
{ name: 'Game Master', age: 40, alive: false },
{ name: 'Camel', age: 22, alive: true }
];
for(let data of dataList) {
console.log("All data info");
console.log(data);
for(let propertyValue of Object.values(data)) {
console.log(propertyValue);
}
}
The Results:
VM1123:2 All data info VM1123:3 {name: 'Eugene', age: 20, alive:
true} VM1123:6 Eugene VM1123:6 20 VM1123:6 true
VM1123:2 All data info VM1123:3 {name: 'Game Master', age: 40,
alive: false} VM1123:6 Game Master VM1123:6 40 VM1123:6
false VM1123:2 All data info VM1123:3 {name: 'Camel', age:
22, alive: true} VM1123:6 Camel VM1123:6 22 VM1123:6
true
I'm trying to achieve the same result, but this time iterating between ngFor directive, like below:
<tr *ngFor="let data of tableConfig.data; let i = index">
<td *ngFor="let propValue of Object.values(data)"> {{ propValue }}</td>
But, the problem is that I can't access the 'Object' class inside the component HTML.
Property 'Object' does not exist on type 'PaginationTableComponent'.
Add method to get your object values like
getValues(data): any{
return Object.values(data);
}
In template :
<td *ngFor="let propValue of getValues(data)"> {{ propValue }}</td>
Demo

JSON multiple alias names angular 8

I have below interface.
interface ProductJson {
id: number;
name: string;
price: number;
}
I want to have multiple alias names for price, like price and alias names: rate, etc. How can I read json data attribute 'rate' for 'price' and also read 'price' too.
You can use a custom serializer to create aliases between fields:
Example using #kaiu/serializer:
class ProductJson {
id: number;
name: string;
#FieldName('rate')
price: number;
}
Or you can also create a getter method and use the serializert to map your JSON to a class instance in order to use your method directly, see https://kaiu-lab.github.io/serializer/ for in-depth stuff.
One way is to maintain a group of attribute names that you want to alias.
And then add the interface property price to the json itself, if it contains the aliased properties like rate or amount.
Now you can simply access price from else where, which should give the same value
Ex:
var price_group = ['price', 'rate', 'amount'];
var some_other_group = []
var resp = {rate: 200, p: 12}
var resp2 = {price: 300, p: 12};
Object.keys(resp).forEach(key => {
if(price_group.indexOf(key) > -1){
resp.price = resp[key]
}
});
console.log(resp.price)
Object.keys(resp2).forEach(key => {
if(price_group.indexOf(key) > -1){
resp.price = resp[key]
}
});
console.log(resp2.price)
I'm not sure you can do that tbh.
You can easily do it by programming your stuff that reads/writes the json to accept stuff like rate, price, moolah and just write it as
{
price: number
}
edit: what i'm saying is you take the user input or any other input that specifies something like {moolah: 30} and you take that '30' and put it on {price: 30} in your json.

Sequelize create with associations

I have been trying to define a relationship between 3 tables and then create them all in one create function. For some reason, while creating the 3 models, the linking IDs (foreign keys) are undefined and are not passing on. Here are the associations:
Person.js:
models.person.Lead = models.person.hasMany(models.lead, {
onDelete: "CASCADE",
foreignKey: "person_id"
});
Lead.js:
models.lead.Person = models.lead.belongsTo(models.person, {foreignKey: 'person_id'});
models.lead.Sealant_customer = models.lead.hasOne(models.sealant_customer, {
onDelete: "CASCADE",
foreignKey: 'lead_id'
})
sealantCustomer.js:
models.sealant_customer.Lead = models.sealant_customer.belongsTo(models.lead);
The build function:
let sealantCustomer = models.sealant_customer.build({
address: body.address,
city: body.city,
roof_size: body.roofSize,
last_sealed: body.lastSealed,
existingSealant: body.existingSealant,
leaks_freq: body.leaksFrequency,
floor: body.floor,
elevator: body.elevator,
panels: body.panels,
home_type: body.homeType,
urgency: body.urgency,
next_step: body.nextStep,
more_info: body.moreInfo,
lead: {
site,
url: body.url,
date,
ip: body.ip,
person: {
name: body.name,
email: body.email,
phone: body.phone,
date,
city: body.city ? body.city : undefined,
address: body.address ? body.address : undefined,
}
}
}, {
include: [{
model: models.lead,
association: models.sealant_customer.Lead,
include: [{
model: models.person,
association: models.lead.Person
}]
}]
})
The outputted object is good except for the fact that lead_id and person_id are nulls (Each model has its own ID, but not the associated model's id). I also should note there are no validation errors and the data is good.
The library has a bug in the build function as far as I can tell. Same syntax with create worked perfectly.
In Sequelize v6, the association identifier in the include section is not valid. Otherwise, this build function should properly work.

How to do cascading inserts with tables having auto increment id columns in TypeORM

I am trying to implement cascading inserts using typeorm. The child table entries include a foreign key reference to the ID field on the parent table.
It seems typeorm is not capturing the auto-increment id from the parent row and supplying it to the child inserts.
Here is the parent Entity:
import ...
#Entity("parent")
export class Parent {
#PrimaryGeneratedColumn()
id: number;
#OneToOne(type => Account, accountId => accountId.provider)
#JoinColumn({name: "account_id"})
accountId: Account;
#Column("varchar", {
name: "name",
nullable: false,
length: 255,
})
name: string;
#OneToMany(type => Child, Children => Children.parentId, {
cascadeInsert: true,
cascadeUpdate: true
})
Children: Child[];
}
and the child entity:
import ...
#Entity("child")
export class Child{
#PrimaryGeneratedColumn()
id: number;
#ManyToOne(type => Parent, parentId => parentId.children)
#JoinColumn({name: "parent_id"})
parentId: Parent;
#Column("varchar", {
name: "number",
nullable: true,
length: 45,
})
number: string;
}
the console log shows that the sql being generated does not include the foreign key column, producing the obvious error ER_NO_DEFAULT_FOR_FIELD: Field 'parent_id' doesn't have a default value
info: executing query: START TRANSACTION
info: executing query: INSERT INTO parent(name, account_id) VALUES (?,?) -- PARAMETERS: ["Name","id"]
info: executing query: INSERT INTO child(number) VALUES (?) -- PARAMETERS: ["12345678"]
info: query failed: INSERT INTO child(number) VALUES (?) -- PARAMETERS: ["12345678"]
info: error: { Error: ER_NO_DEFAULT_FOR_FIELD: Field 'parent_id' doesn't have a default value
Is there some way that typeorm can be instructed to capture the LAST_INSERT_ID() or otherwise populate the foregin key id field on the child row?
If the id is not auto generated, but assigned before saving the entity, it works.
Use a uuid as primary key.
import ...
#Entity("parent")
export class Parent {
#PrimaryColumn()
id: string;
#OneToOne(type => Account, accountId => accountId.provider)
#JoinColumn({name: "account_id"})
accountId: Account;
#Column("varchar", {
name: "name",
nullable: false,
length: 255,
})
name: string;
#OneToMany(type => Child, Children => Children.parentId, {
cascadeInsert: true,
cascadeUpdate: true
})
Children: Child[];
}
and when you create the entity.
const parent: Parent = new Parent();
parent.id = "896b677f-fb14-11e0-b14d-d11ca798dbac"; // your uuid goes here
Unfortunately you can not use #PrimaryGeneratedColumn("uuid") either.
There are a lot of libraries to generate a uuid in JS.
Example with uuid-js - https://github.com/pnegri/uuid-js
const parent: Parent = new Parent();
parent.id = UUID.create(4).toString();
I think this is more like a workaround, rather than a solution to the problem. But I could not find a way to tell TypeORM to consider generated ids when cascading children.

AngularJS Iteratively Create Picklists with Options

I would like to know how to iteratively create picklists (dropdowns) from a json collection.
I have two desired columns, one representing the 'primary' category, and the other representing the 'secondary' category.
I'd like for the right column to have just a string for every 'primary' category and then the left column will have a picklist with options for secondary category. What i'm also trying to do is group this by type. So there will essentially be sections of picklists grouped by type. One section with two columns of 'string', and then another section below that one with two columns of 'number', etc.
--Numbers--
Column 1 || Column 2
Label || picklist
--Strings--
Column 1 || Column 2
Label || picklist
--Booleans--
Column 1 || Column 2
Label || picklist
function MyCtrl($scope) {
$scope.players = [
{type: 'String', org: 'primary', name: 'something__c', label: 'Something'},
{type: 'Number', org: 'primary', name: 'something_else__c', label: 'Something Else'},
{type: 'String', org: 'primary', name: 'obscure__c', label: 'Obscure'},
{type: 'String', org: 'primary', name: 'else__c', label: 'Else'},
{type: 'String', org: 'secondary', name: 'some__c', label: 'Some'},
{type: 'Number', org: 'secondary', name: 'thing__c', label: 'Thing'},
{type: 'Number', org: 'secondary', name: 'sanity_check__c', label: 'My Sanity'}
];
}
Using the tutorials i was only able to get as far as what is in this fiddle: http://jsfiddle.net/GV7KZ/5/
Thank you for any and all guidance.
I'm assuming you mean 'org' instead of category, given that org is the only node with the values of 'primary' and 'secondary'. I thing perhaps you want to use 'filter' rather than your custom 'group by' filtering.
I've made some changes to your fiddle separating out the two. Let me know if this gets you closer to what you want.
<tr ng-repeat="player in players|filter:'primary'">
<td>
{{player.label}}
</td>
<td>
<select>
<option ng-repeat="player in players|filter:'secondary'" value="{{player.name}}">{{player.label}}</option>
</select>
</td>
http://jsfiddle.net/GV7KZ/6/