How can I get the calculated field work in Angular 2? - angular2-template

I am trying to get the data from a calculated field
export class Position {
securityId: number;
securityName: string;
tradeCount: number;
avgPrice: number;
quantity: number;
constructor () {}
public get marketValue(): number {
return this.avgPrice * this.quantity;
}
}
And I am tryinhg to bind all the fields which work fine but the calculated marketValue does not
td>{{ position.marketValue | currency:"USD":true:"1.2-2"}}</td>
The table cell shows empty. However the following does work
td>{{ this.quantity * this.avgPrice | currency:"USD":true:"1.2-2"}}</td>
How can I get the caclcualed property to work?
Thanks!

Change
td>{{ position.marketValue | currency:"USD":true:"1.2-2"}}</td>
to
td>{{ this.marketValue | currency:"USD":true:"1.2-2"}}</td>

export class Position {
securityId: number;
securityName: string;
tradeCount: number;
avgPrice: number;
quantity: number;
marketValue: number;
constructor () {}
ngOnChanges(change) {
this.marketValue = this.avgPrice * this.quantity;
}
}

Related

How to create SQL query with multiple JSON parameters in golang application?

As you can see in my Golang application I have an array called layers.
type Details struct {
Total int `json:"total"`
Gender string `json:"gender"`
}
type Layer struct {
ID int `json:"id"`
City string `json:"city"`
Details []Details `json:"details"`
}
layers := []Layer{
{
ID: 107509018555,
City: "London",
Details: []Details{
{
Total: 158,
Gender: "Male",
},
{
Total: 689,
Gender: "Female",
},
},
},
{
ID: 108509018556,
City: "New York",
Details: []Details{
{
Total: 756,
Gender: "Male",
},
{
Total: 356,
Gender: "Female",
},
},
},
}
I want to insert data of that array to the table of the PostgreSQL database. My question is how to create such SQL query in the application?
QUERY:
INSERT INTO layers (ID, CITY, DETAILS) VALUES
(107509018555, 'London', '[{"total":158,"gender":"Male"},{"total":689,"gender":"Female"}]'::json),
(108509018556, 'New York', '[{"total":756,"gender":"Male"},{"total":356,"gender":"Female"}]':json);
Because I cannot comment, I assume that:
You're using golang's database/sql or similar package.
In your database, details column has type JSONB
A simple approach is to loop your slice layers and build query string to this:
"INSERT INTO layers (id,city,details) VALUES ($1,$2,$3), ($4,$5,$6)"
For id and city, you can pass the params easily, however you need to pass JSON bytes for details. Which means, you'll need to marshal Details struct to JSON bytes for insert/update and unmarshal 'details' result to struct when SELECT
You will need to:
Define new struct that encapsulates the slice of Detail (we'll call it Details) then the Details should implement these interfaces.
Implements driver.Valuer interface to convert Details to JSON byte slice that can be understood by the database
Implements sql.Scanner interface to unmarshal JSON byte slice from database to your struct
The code should look like this:
type Detail struct {
Total int `json:"total"`
Gender string `json:"gender"`
}
// this will implement driver.Valuer and sql.Scanner
type Details []Detail
// so that the database can understand your value, useful for INSERT/UPDATE
func (d Details) Value() (driver.Value, error) {
return json.Marshal(d)
}
// so that the database can convert db value to your struct, useful for SELECT
func (d *Details) Scan(value interface{}) error {
b, ok := value.([]byte)
if !ok {
return errors.New("type assertion to []byte failed for scanning Details")
}
return json.Unmarshal(b, &d)
}
The complete code:
package main
import (
"database/sql"
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
"log"
"strings"
_ "github.com/lib/pq"
)
type Layer struct {
ID int `json:"id"`
City string `json:"city"`
Details Details `json:"details"`
}
// this will implement driver.Valuer and sql.Scanner
type Details []Detail
// so that the database can understand your value, useful for INSERT/UPDATE
func (d Details) Value() (driver.Value, error) {
return json.Marshal(d)
}
// so that the database can convert db value to your struct, useful for SELECT
func (d *Details) Scan(value interface{}) error {
b, ok := value.([]byte)
if !ok {
return errors.New("type assertion to []byte failed for scanning Details")
}
return json.Unmarshal(b, &d)
}
type Detail struct {
Total int `json:"total"`
Gender string `json:"gender"`
}
func main() {
db, err := sql.Open("postgres", "postgres://user:pass#host:port/db?sslmode=disable")
exitIfError(err)
query, params := prepareQuery([]Layer{
{
ID: 107509018555,
City: "London",
Details: []Detail{{Total: 158, Gender: "Male"}, {Total: 689, Gender: "Female"}},
},
{
ID: 108509018556,
City: "New York",
Details: []Detail{{Total: 756, Gender: "Male"}, {Total: 356, Gender: "Female"}},
},
})
log.Println(query)
// INSERT INTO layers (id, city, details) VALUES ($1, $2, $3),($4, $5, $6)
log.Println(params)
// [107509018555 London [{158 Male} {689 Female}] 108509018556 New York [{756 Male} {356 Female}]]
result, err := db.Exec(query, params...)
exitIfError(err)
rows, _ := result.RowsAffected()
log.Println(rows) // 2 rows inserted
}
func exitIfError(err error) {
if err != nil {
log.Fatal(err)
}
}
func prepareQuery(layers []Layer) (string, []interface{}) {
query := "INSERT INTO layers (id, city, details) VALUES "
params := []interface{}{}
x := 1
for _, layer := range layers {
query += fmt.Sprintf("($%d, $%d, $%d),", x, x+1, x+2)
params = append(params, layer.ID, layer.City, layer.Details)
x += 3
}
query = strings.TrimSuffix(query, ",")
return query, params
}
Reference:
https://www.alexedwards.net/blog/using-postgresql-jsonb
https://golang.org/pkg/database/sql/

Short variabledeclaration with multiple variables

the problem is when you have one variable declared but the other no and you declare them with the := you will get error so what's the solution
example
var number *int
func(num *int) {
num,err := function() // that returns int and error
}
but here you will get error because num is already declared so what to do
declare err
var err error
but what if i need to use it in another thing which i need short declaration??
Here:
func f(num *int) {
num,err := function() // that returns int and error
}
if function returns (int,error), then you are trying to assign an int to a *int, and that's the reason why you get an error. If function returns *int, everything works fine.
If you need to redeclare num regardless, you can create a new scope:
func f(num *int) {
{
num,err:=function()
// Here, num is int
...
}
}

MobX decorating a class causes function to throw TypeError

I have two data classes (business logic that I didn't write), that I'm trying to use in a store. I have fixed issues in that store by decorating them. They are defined to be:
// data classes; // these would be in separate file.
class PayRate {
/**
* #param {number} storeId The store id of the pay rate. (-1 for all)
* #param {number} empId The id of the employee. (-1 for all)
* #param {number} taskId The id of the task. (-1 for all)
* #param {Date} effectiveDate The date the payrate goes in effect.
* #param {number} rate The rate of pay.
*/
constructor(storeId, empId, taskId, effectiveDate, rate) {
this.StoreId = storeId || -1;
this.EmpId = empId || -1;
this.TaskId = taskId || -1;
this.EffectiveDate = effectiveDate ? new Date(effectiveDate) : new Date();
this.Rate = rate || 0.00;
this.OriginalObject = $.extend(true, {}, this);
}
/**
* Gets a readable version of the effective date.
* #returns {string} A -m/dd/yyyy representation of the effective date.
*/
GetReadableDate() {
return this.EffectiveDate.toLocaleDateString("en-US");
}
/**
* Gets a one line description of the pay rate.
* #returns {string} A string in the form of (date) - payrate.
*/
GetDescription() {
return `(${this.GetReadableDate()}) - $${this.Rate.toFixed(2)}`;
}
/**
* Gets a one line description of the pay rate.
* Does the exact same as GetDescription(), but is overload of Object.prototype.toString, which allows for stringification of Objects
* #returns {string} A string in the form of (date) - payrate.
*/
toString() {
return `(${this.GetReadableDate()}) - $${this.Rate.toFixed(2)}`;
}
/**
* Tells whether a pay rate was changed or not.
* #returns {boolean} A boolean saying whether or not the pay rate was changed.
*/
IsChanged() {
if (this.EffectiveDate.getTime() !== this.OriginalObject.EffectiveDate.getTime()) {
return true;
}
if (this.Rate != this.OriginalObject.Rate) {
return true;
}
if (this._deleted) {
return true;
}
return false;
}
/**
* Reverts the changes back to the original.
*/
RevertChanges() {
$.extend(true, this, this.OriginalObject);
}
}
mobx.decorate(PayRate, {
StoreId : mobx.observable,
EmpId : mobx.observable,
TaskId : mobx.observable,
EffectiveDate : mobx.observable,
Rate : mobx.observable,
})
class TaskObject {
/**
* #param {Task} task The task that is being kept track of.
* #param {PermissionLink[]} permissionLinks A list of permission links that are being kept track of.
* #param {PayRate[]} payrates A list of pay rates that are being kept track of.
*/
constructor(task, permissionLinks = [], payrates = []) {
this.Model = $.extend(true, {}, task);
this.Model.Type = 25;
this.PermissionLinks = $.extend(true, [], permissionLinks);
this.Payrates = $.extend(true, [], payrates);
this.OriginalObject = $.extend(true, {}, this);
}
/**
* Gives the dirty status of the task object.
* #returns {boolean} Tells whether or not the TaskObject has been changed.
*/
IsChanged() {
if (this.Model.Id == -1) {
return true;
}
if (this.Model.Name != this.OriginalObject.Model.Name) {
return true;
}
if (this.Model.GroupName != this.OriginalObject.Model.GroupName) {
return true;
}
if (this.Model.DescStr != this.OriginalObject.Model.DescStr) {
return true;
}
if (this.Model.IsActive != this.OriginalObject.Model.IsActive) {
return true;
}
if (this.PermissionLinks.length != this.OriginalObject.PermissionLinks.length) {
return true;
}
for (let i = 0; i < this.PermissionLinks.length; i++) {
const element = this.PermissionLinks[i];
const compElement = this.OriginalObject.PermissionLinks[i];
if (JSON.stringify(element) !== JSON.stringify(compElement)) {
return true;
}
}
for (let i = 0; i < this.Payrates.length; i++) {
const payrate = this.Payrates[i];
if (payrate.IsChanged()) {
return true;
}
}
return false
}
/**
* Reverts the changes that are on the task object.
* #returns {TaskObject} The TaskObject with its changes discarded.
*/
RevertChanges() {
this.Model = $.extend(true, {}, this.OriginalObject.Model);
this.PermissionLinks = $.extend(true, [], this.OriginalObject.PermissionLinks);
for (let i = 0; i < this.Payrates.length; i++) {
this.Payrates[i].RevertChanges()
}
return this;
}
/**
* This is here for debugging purposes (i.e. with data stores that use it) and may be overwritten with business logic at any time
*/
toString() {
return JSON.stringify(this, null, '\t')
}
}
// marking all the properties of TaskObject observable
mobx.decorate(TaskObject, {
Model : mobx.observable,
PermissionLinks : mobx.observable,
Payrates : mobx.observable,
RevertChanges : mobx.action,
IsChanged : mobx.computed
})
Now, doing new PayRate().IsChanged() works as expected, but new TaskObject.IsChanged() results in:
Uncaught TypeError: Cannot read property 'call' of undefined
at e.computeValue (mobx.umd.min.js:1)
at e.get (mobx.umd.min.js:1)
at e.read (mobx.umd.min.js:1)
at TaskObject.get (mobx.umd.min.js:1)
at pen.js:163
e.computeValue # mobx.umd.min.js:1
e.get # mobx.umd.min.js:1
e.read # mobx.umd.min.js:1
get # mobx.umd.min.js:1
(anonymous) # pen.js:163
Here is demo
Why is this happening and how can I fix it?
You declare IsChanged as a function but decorate it as a computed property, then call it as a function. If you want it to be a computed property, you'd need to:
convert it to a getter: IsChanged() -> get IsChanged()
call it without parenthesis: TaskObject.IsChanged

Bind combobox with OO

I have 2 business classes. This classes are load by database. The "product" class have a property "category" who is an instance of category.
unit Unit5;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, Generics.Collections,
FMX.Edit, FMX.ListBox, FMX.Controls.Presentation, FMX.StdCtrls,
Data.Bind.Components, Data.Bind.ObjectScope, Data.Bind.GenData,
FMX.Bind.Editors, System.Rtti, System.Bindings.Outputs,
Data.Bind.EngExt, FMX.Bind.DBEngExt;
type
TCategory = class
private
FName : String;
FShortName: String;
FID : integer;
public
constructor Create(IDFromDataBase: integer; NameFromDataBase: string);
property ID: integer read FID write FID;
property Name: String read FName write FName;
end;
TProduct = class
private
FID : integer;
FName : string;
FCategory: TCategory;
public
constructor Create(IDFromDataBase: integer; NameFromDataBase: string; Cat: TCategory);
property ID: integer read FID write FID;
property Name: string read FName write FName;
property Category: TCategory read FCategory write FCategory;
end;
TForm5 = class(TForm)
Label1: TLabel;
Category: TLabel;
ComboProductCategory: TComboBox;
EditProductName: TEdit;
PrototypeBindSourceCategory: TPrototypeBindSource;
PrototypeBindSourceProduct: TPrototypeBindSource;
procedure FormCreate(Sender: TObject);
procedure PrototypeBindSourceProductCreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
procedure PrototypeBindSourceCategoryCreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
private
{ Déclarations privées }
FListCategory: TObjectList<TCategory>;
FProduct : TProduct;
public
{ Déclarations publiques }
constructor Create(AOwner: TComponent); override;
end;
var
Form5: TForm5;
implementation
{$R *.fmx}
{ TCategory }
constructor TCategory.Create(IDFromDataBase: integer; NameFromDataBase: string);
begin
inherited Create;
FID := IDFromDataBase;
FName := NameFromDataBase;
end;
{ TProduct }
constructor TProduct.Create(IDFromDataBase: integer; NameFromDataBase: string; Cat: TCategory);
begin
inherited Create;
FID := IDFromDataBase;
FName := NameFromDataBase;
FCategory := Cat;
end;
constructor TForm5.Create(AOwner: TComponent);
begin
FListCategory := TObjectList<TCategory>.Create();
// Normaly load by query on database
FListCategory.Add(TCategory.Create(1, 'Clothe'));
FListCategory.Add(TCategory.Create(2, 'Luxury'));
FProduct := TProduct.Create(1, 'Clock', FListCategory.Items[1]);
inherited Create(AOwner);
end;
procedure TForm5.FormCreate(Sender: TObject);
var
// Bind sur un TEdit
LinkControl: TLinkControlToField;
ListLink : TLinkFillControlToField;
begin
PrototypeBindSourceProduct.Active := false;
PrototypeBindSourceCategory.Active := false;
try
// Bind product name on edit.
LinkControl := TLinkControlToField.Create(self);
LinkControl.DataSource := PrototypeBindSourceProduct;
LinkControl.FieldName := 'Name';
LinkControl.Control := EditProductName;
LinkControl.Track := true;
// Bind combo.
ListLink := TLinkFillControlToField.Create(self);
ListLink.DataSource := PrototypeBindSourceProduct;
ListLink.FieldName := 'Category.ID';
ListLink.Control := ComboProductCategory;
ListLink.FillDataSource := PrototypeBindSourceCategory;
ListLink.FillValueFieldName := 'ID';
ListLink.FillDisplayFieldName := 'Name';
ListLink.AutoFill := true;
ListLink.Track := true;
finally
PrototypeBindSourceCategory.Active := true;
PrototypeBindSourceProduct.Active := true;
end;
end;
procedure TForm5.PrototypeBindSourceCategoryCreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
begin
ABindSourceAdapter := TListBindSourceAdapter<TCategory>.Create(self, FListCategory);
end;
procedure TForm5.PrototypeBindSourceProductCreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
begin
ABindSourceAdapter := TObjectBindSourceAdapter<TProduct>.Create(self, FProduct);
end;
end.
But when I start program, the combobox it's loaded with the list of categories. But I have not the selected item.
I think the problem it here :
ListLink.FieldName := 'Category.ID';
I don't want create an "CategoryID" on my class "product".
What is the good way for bind a combobox on OO classes ?

Smalltalk - Methods with Multiple Parameters [duplicate]

Say I'm trying to translate the below Java classes to GNU Smalltalk:
public abstract class Account {
protected String number;
protected Customer customer;
protected double balance;
public abstract void accrue(double rate);
public double balance() {
return balance;
}
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) {
balance -= amount;
}
public String toString() {
return number + ":" + customer + ":" + balance;
}
}
public class SavingsAccount extends Account {
private double interest = 0;
public SavingsAccount(String number, Customer customer, double balance) {
this.number = number;
this.customer = customer;
this.balance = balance;
}
public void accrue(double rate) {
balance += balance * rate;
interest += interest * rate;
}
}
I'm struggling to understand how I can write methods/constructors that take multiple parameters. Here's what I've got so far:
Object subclass: Account [
|number customer balance|
balance [
^balance
]
deposit: amount [
balance := balance + amount
]
withdraw: amount [
balance := balance - amount
]
asString [
^number asString, ':', customer asString, ':', balance asString
]
]
Account subclass: SavingsAccount [
|interest|
SavingsAccount class [
new [ "add some sort of support for multiple arguments?"
"call init"
]
]
init [ "add some sort of support for multiple arguments?"
interest := 0.
balance := accountBalance.
customer := accountCustomer.
number := accountNumber
]
accrue: rate [
balance := balance + (balance * rate).
interest := interest + (interest * rate)
]
]
A few questions:
How can I make Account an abstract class in Smalltalk?
Am I correct in assuming all the Account instance variables are just accessible by name in the SavingsAccount Class?
How can I implement something that mimics the multiple parameter constructor in the Java SavingsAccount Class?
You shouldn't bother with some kind of "making class abstract" :). But the closest solution to your question is
abstractMethod [
self subclassResponsibility
]
Now when someone sends a message to your class he'll get an error that this method should be implemented, and you must override it in subclasses.
Yes. All instance vars can be accessed by a subclass.
Ok, so the keyword messages like withdraw: amount can actually have multiple parameters like: withdraw: amount becauseOf: reason. So first of all you make an initialiser:
initWithBalance: aBalance customer: aCustomer number: aNumber [
self init.
balance := aBalance.
customer := aCustomer.
number := aNumber
]
You can keep interest := 0. in main init.
Then, to make your life better, you make a parameterised new and call parameterised init from there.
SavingsAccount class [
newWithBalance: aBalance customer: aCustomer number: aNumber [
^ self new initWithBalance: aBalance customer: aCustomer number: aNumber
]
]