Show one of the two values in the template - polymer

I have a simple element:
<dom-module id="example-element">
<template>
<span>{{showAorB??}}</span>
</template>
<script>
Polyemer({
is: 'example-element',
parameters: {
a: String,
b: String
}
});
</script>
</dom-module>
I use it like this:
<example-element a="{{a}}" b="{{b}}">
In my scenario, one of a or b is always undefined.
What I'm confused about is how to implement {{showAorB}} part. Essentially what I want is something like a || b.
What I've tried:
computed property / function ({{showAorB(a,b)}}) - doesn't work because it waits for both a and b to be !== undefined which, in my case, means it waits forever
<span hidden$='{{!a}}'>{{a}}</span><span hidden$='{{!b}}'>{{b}}</span> - it's just awkward
What's the proper way to implement this?

Use the function syntax ({{showAorB(a,b)}}) but in your properties declaration (you showed parameters but it should be properties) give a and b falsey (but not undefined) values. Like so:
properties: {
a: {
value: ''
},
b: {
value: ''
}
},
Live example: http://jsbin.com/jazava/edit?html,output

Related

How to show a particular URL to the user depending on JSON input using ngIf? (Angular)

In Angular, how to use *ngIf to check whether a JSON value includes a certain string, and then show them a certain URL ? In my case I have a object name called campaigns.description which has a value that includes a description. I want to see whether a given string, for example "one beam" is included in that description and show an URL based on that.
So not the way that the value equals a certain string, but the text that is held within the value includes a certain string.
You can use indexof() function to check the existence of some substring inside a string. This function returns '-1' if the substring is not present in the string.
<label *ngIf="campaigns.description.indexOf('One Beam') != -1 ? true : false">{{urlToShow}}</label>
You could generally use indexOf to check whether a string contains a sub-string.
console.log("Sample string".indexOf('string'));
console.log("Sample string".indexOf('not'));
The Angular part:
Trivial (not recommended)
Trivial solution is to check directly in the *ngIf condition
<div *ngIf="campaigns.description.indexOf('one beam') !== -1; else other">
<!-- contains the sub-string -->
</div>
<ng-template #other>
<!-- does not contain the sub-string -->
</ng-template>
However binding a function to *ngIf directive with default change detection strategy would trigger the function for each change detection cycle. It might lead to performance issues.
Additional property (recommended)
You could introduce additional property to hold the result of the condition in the controller and use it in the template.
Controller (*.ts)
// I assume `campaigns` is initialized in a subscription
ngOnInit() {
someObservable.subscription(
(res: any) => {
this.campaigns = {
...res,
subString: res.description.indexOf('one beam') !== -1
}
},
(error: any) => { }
);
}
Template (*.html)
<div *ngIf="campaigns?.subString; else other">
<!-- contains the sub-string -->
</div>
<ng-template #other>
<!-- does not contain the sub-string -->
</ng-template>

How to use the global variable in another function? [duplicate]

Im writing a small code using Memcache Go API to Get data stored in one of its keys . Here are few of lines of code i used ( got the code from Go app-engine docs )
import "appengine/memcache"
item := &memcache.Item {
Key: "lyric",
Value: []byte("Oh, give me a home"),
}
But the line 2 gives me a compilation error "expected declaration, found 'IDENT' item"
I'm new to Go , not able to figure out the problem
The := Short variable declaration can only be used inside functions.
So either put the item variable declaration inside a function like this:
import "appengine/memcache"
func MyFunc() {
item := &memcache.Item {
Key: "lyric",
Value: []byte("Oh, give me a home"),
}
// do something with item
}
Or make it a global variable and use the var keyword:
import "appengine/memcache"
var item = &memcache.Item {
Key: "lyric",
Value: []byte("Oh, give me a home"),
}
I was getting the same error, but the reason was completely different.
I was using following package name.
package go-example
Seems like, it's not a valid package name. After removing the hyphen, it worked.
This error also shows up when assigning value to a variable whose name is a keyword
Like using var:= 2
This also causes the error "expected declaration, found 'IDENT' item"
So correct the name and it will be fine

Waterline - Where with sum of fields

I've got the following model Test
module.exports = {
attributes: {
a: {
type: 'number'
},
b: {
type: 'number'
}
}
}
I would like to build a query that allows me to put sum of fields a and b in where statement.
SQL equavilent:
SELECT * FROM Test WHERE a + b = myValue
I read in sails doc's about Criteria modifiers but there is no word about that.
Is there any clever way to do that? Of course I can use native query but I would like to avoid that because I must use the sum along with other modifiers. The reason is I'm generating dynamic queries from separate files and with native queries I will have to also handle already defined functionality like or, and, etc.
I found a workaround. Maybe it will be useful to someone.
It is not stricte sails/node solution, but database one, however, it fits my case perfectly.
From MySQL 5.7 there is something like generated columns.
Columns are generated because the data in these columns are computed based on predefined expressions.
All I had to do was add an extra, auto generated column to my Test model:
module.exports = {
attributes: {
a: {
type: 'number',
columnType: 'int'
},
b: {
type: 'number',
columnType: 'int'
},
c: {
type: 'number',
columnType: 'int GENERATED ALWAYS AS(a + b) VIRTUAL'
}
}
}
Now I'm able to do such query:
const result = await Test.find({ c: 2 })
...and I get the correct result. Waterline treats my column like any other, database does everything instead of me.
Of course I can mix it with other modifiers with no problems.
I haven't seen any complications so far.

angular 2+ component with attribute name and no parameters

I want to allow a user to provide a list of one-word attributes without parameter values. For example,
<container row crosscenter wrap spacearound ...>
which results in something like this in container.html
<div [ngClass]="{ 'flexDisplay': true, 'directionRow': isRow, 'directionCol': isCol, 'contentSpaceAround': isSpaceAround}" ...>
What I'm missing is how to set
#Input('row') isRow = false;
to true if 'row' was present in the container line.
Any ideas?
Thanks in advance.
Yogi
This can be handled in ngOnChanges. The value can be assigned either back to input property or to some object that will be passed to ngClass
ngOnChanges(changes: SimpleChanges) {
if ('foo' in changes) {
this.options.foo = true;
}
}
Since there's no way how inputs can become unassigned, there's no reason to provide bindings for them. #Attribute can be used instead:
constructor(#Attribute('foo') public foo: boolean|null) {
this.foo = (foo != null);
}
Using attributes for regular options isn't a good decision, design-wise. This prevents from setting them dynamically. Instead, it is always preferable to accept options input. If all options are supposed to be flags, it can be a string input that will be split and processed in ngOnChanges, like:
<container options="row crosscenter wrap spacearound">
or
<container [options]="'row crosscenter wrap spacearound'">
I think the answer to my question is to create directives for each of the "one-word" tags (attributes) I want to use.
:-)

Dynamic ng-Grid with JSON data in angularJS?

I want to make a dynamic ng-grid , which adjusts its columns according to the key values in my JSON object. JSON object is fetched from an api. the problem I am facing is defining columns at runtime i.e The columns are not available at design time but will only be available only at runtime. I want to have something like :
http://plnkr.co/edit/q1Ye10OsIn9NOJmrICyD?p=preview
So that, I have as many columns as keys in my Json object. API's can vary so I need to make a grid which adjusts its columns.
My plunker is not working, but I hope it gives you idea, what I am trying to do.
Unless I'm misunderstanding what you want, you don't need to mess with columnDefines. Just having this:
faculty.controller('facultycontroller', function facultycontroller($scope, $http, $window){
$scope.facdata = [];
$scope.gridOptions = {
data: 'facdata'
};
$http.get("http://mtapi.azurewebsites.net/api/institute").then(function (result) {
$scope.facdata = result.data;
console.log($scope.facdata[0]);
});
});
will create the grid with a column for each key in your json.
Update
If you want to filter out any columns that begin with '$', you can do something like this:
angular.forEach(result.data[0], function(value, key){
if(key.indexOf('$') != 0)
$scope.columnDefines.push({ field: key, displayName: key});
});
Actually, you were close with what you were trying to do. You just need to put the columnDefines variable on $scope, and assign it to the gridOptions using a string, like this:
$scope.columnDefines = [];
$scope.gridOptions = {
data: 'facdata',
columnDefs: 'columnDefines'
};
Plunker
Try attaching your columnDefines variable to the scope ($scope.columnDefines). Then in your options do this:
$scope.gridOptions =
{
data: 'facdata',
columnDefs: 'columnDefines' //Note the quotes
};
This will make ng-grid watch your columnDefs for changes