How to define functions within a function in typescript? - ios

I know basic Javascript, but am confronted with a problem in a Typescript file. I'm using Ionic framework to test a page where a user can theoretically "swipe" like they're on Tinder, just for fun.
I have all the JS written, because I'm moving this over from Codepen, but I can't seem to get past Typescript's syntax.
The Javascript:
var tinderContainer = document.querySelector('.tinder');
var allCards = document.querySelectorAll('.tinder--card');
var nope = document.getElementById('nope');
var love = document.getElementById('love');
function initCards(card, index) {
var newCards = document.querySelectorAll('.tinder--card:not(.removed)');
newCards.forEach(function (card, index) {
card.style.zIndex = allCards.length - index;
}
}
The Typescript (that I put together using Google and SOF answers):
export class TestPage {
constructor(public navCtrl: NavController) {
}
tinderContainer = document.querySelector('ion-content');
allCards = document.querySelector('.tinder--card');
nope = document.getElementById('nope');
love = document.getElementById('love');
declare initCards(card,index) {
newCards = document.querySelectorAll('.tinder--card:not(.removed)');
newCards.forEach((card,index)) {
card.style.zIndex = allCards.length - index;
}
}
}

some hints are:
Use let newCards in you function as you have to declare your variable.
Your forEach should be something like this.
newCards.forEach((card, index) => {
...
});
but in order to use syntax like card.style.zIndex and allCards.length you will have to declare variable types..
For unknown models you can use something like card['style']['zIndex']
Also you have to use this to access class properties, like this.allCards

Related

How can I use a std::variant with non-trivial user objects (constructed at a later time), and having the visitor use an auto lambda?

I have code that is something like this:
using variant_t = std::variant<MyObj1, MyObj2, MyObj3>;
auto foo(){
variant_t var;
if (condition1){
var = MyObj1{"A String"};
// Other stuff
} else if (condition2) {
var = MyObj2{123, 12345};
// Other stuff
} else if (condition3) {
var = MyObj3{SomeObject};
// Other stuff
} else {
throw std::runtime_error{};
}
return var;
}
int main(){
auto var = foo();
std::visit([&](auto& v){v.call_shared_function_name();}, var);
}
Assuming all of the MyObj's are non-trivial, is there a way to get this to work?
I know std::monostate will allow you to initialize the variant in this way and actually populate it later. But if I do so, I can't have the clean auto& lambda in the visitor and will have to create a visitor/lambda for each type.
I know this might looks silly, or not that clean, but you actually need to initialize with one of those objects:
variant_t var = MyObj1{"A String"};
And it compiles fine, if you can't, please let me know and i'll remove the answer

Using Vaadin components in a kotlin js project

This question is about a Kotlin JS project which uses the Kotlin Frontend Plugin.
I want to use some UI components from the Vaadin Components library.
I have two questions about this:
(1) What would be the best way to include web components in Kotlin JS
=> for my complete code, see the link to the source below. In summary the relevant details are:
build.gradle.kts
kotlinFrontend {
npm {
dependency("#vaadin/vaadin-grid")
}
}
vaadin.grid.Imports.kt
#file:JsModule("#vaadin/vaadin-grid")
#file:JsNonModule
package vaadin.grid
external class GridElement {
companion object
}
Why the companion object? I need it for the workaround (see below).
foo.kt
fun main() {
document.getElementById("container")!!.append {
vaadin_grid {
attributes["id"] = "grid"
}
}
initUI()
}
fun initUI() {
// Force the side-effects of the vaadin modules. Is there a better way?
console.log(GridElement)
val grid = document.querySelector("#grid") /* ?? as GridElement ?? */
}
The console.log is the ugly workaround trick I want to avoid. If I don't do anything with GridElement then it's just not included in my bundle.
The vaadin_grid DSL is defined as a custom kotlinx.html tag which is unrelated code.
(2) I want to keep my code as typed as possible to avoid asDynamic but when I cast the HTMLElement to a Vaadin Element I get ClassCastExceptions (because GridElement is undefined).
For example I want to write something like this:
val grid : GridElement = document.querySelector("#grid") as GridElement
grid.items = ... // vs grid.asDynamic().items which does work
Here is how I define the external GridElement
vaadin/button/Imports.kt
#file:JsModule("#vaadin/vaadin-grid")
#file:JsNonModule
package vaadin.grid
import org.w3c.dom.HTMLElement
abstract external class GridElement : HTMLElement {
var items: Array<*> = definedExternally
}
build/node_modules/#vaadin/vaadin-grid/src/vaadin-grid.js
...
customElements.define(GridElement.is, GridElement);
export { GridElement };
Source example
To run:
From the root of the git repo:
./gradlew 05-kt-frontend-vaadin:build && open 05-kt-frontend-vaadin/frontend.html
I found the answer(s)
For the first question
(1) What would be the best way to include web components in Kotlin JS
Instead of the console.log to trigger the side effects I use require(...)
external fun require(module: String): dynamic
fun main() {
require("#vaadin/vaadin-button")
require("#vaadin/vaadin-text-field")
require("#vaadin/vaadin-grid")
...
}
(credits to someone's answer on the kotlin-frontend-plugin list)
(2) I want to keep my code as typed as possible to avoid asDynamic
Instead of importing #vaadin/vaadin-grid I have to import the file which actually exposes the element. Then it seems to work and I can even add generics to my GridElement:
#file:JsModule("#vaadin/vaadin-grid/src/vaadin-grid")
#file:JsNonModule
package vaadin.grid
import org.w3c.dom.HTMLElement
abstract external class GridElement<T> : HTMLElement {
var items: Array<out T> = definedExternally
}
This way I was able to get rid of all the asDynamics
val firstNameField = document.querySelector("#firstName") as TextFieldElement?
val lastNameField = document.querySelector("#lastName") as TextFieldElement?
val addButton = document.querySelector("#addButton") as ButtonElement?
val grid = document.querySelector("#grid") as GridElement<Person>?
val initialPeople: Array<out Person> = emptyArray()
grid?.items = initialPeople
addButton?.addEventListener("click", {
// Read the new person's data
val person = Person(firstNameField?.value, lastNameField?.value)
// Add it to the items
if(grid != null){
val people = grid.items
grid.items = people.plus(person)
}
// Reset the form fields
firstNameField?.value = ""
lastNameField?.value = ""
})

How do functions with multiple parameters of the same name work?

I've been looking through the code for a Flash game (link). However, I'm having trouble understanding how some of these functions work, especially because some of them have function definitions that I would think to fail to get past the compiler.
The following is some code from TodCommon.as that appears to conflict with itself (or at the very least uses bad naming conventions).
private static var gFlashingColor:Color = new Color();
final public static function ClampFloat(ClampInt:Number, ClampInt:Number, ClampInt:Number) : Number
{
if(ClampInt <= ClampInt)
{
return ClampInt;
}
if(ClampInt >= ClampInt)
{
return ClampInt;
}
return ClampInt;
}
final public static function ClampInt(gFlashingColor:int, gFlashingColor:int, gFlashingColor:int) : int
{
if(gFlashingColor <= gFlashingColor)
{
return gFlashingColor;
}
if(gFlashingColor >= gFlashingColor)
{
return gFlashingColor;
}
return gFlashingColor;
}
Also in the code is the weirdest syntax for a for-each loop that I've ever seen (this example also features a package name as a parameter name)
public function CountPlantByType(com.popcap.flash.framework.resources.fonts:int) : int
{
var _loc_3:CPlant = null;
var _loc_2:int = 0;
var _loc_4:int = 0;
var _loc_5:* = this.mPlants;
while(<to complete>)
{
_loc_3 = __nextvalue;
if(_loc_3.mSeedType != com.popcap.flash.framework.resources.fonts)
{
break;
}
_loc_2++;
}
return _loc_2;
}
Those are just a few examples of things that I think look super weird and am having trouble understanding. But these functions all work and are used extensively throughout the code. Can someone explain how the ClampFloat and ClampInt functions work, or why it's legal to use a package name as a parameter? Thanks
Resolved. Turns out the program I used to extract these files from the SWF also corrupted them in the process. Using JPEXS Free Flash Decompiler instead of ActionScriptExtractor fixed the code syntax.

JavaScript module pattern with sub-modules cross access or better pattern?

Perhaps this is the wrong approach to my problem, but that is why I'm here. In the code below is a sample of a JavaScript module pattern with sub-modules. As I build this, I realize that some sub-modules need to "call" each other's methods.
I know that it would be wrong to use the full call admin.subModuleB.publicB_2(); but its the only way since the IIFE functions cannot call "themselves" until instatiated, ex. "module" is not available in the primary namespace, etc...
My thought is that this pattern is incorrect for my situation. The purpose of the module encapsulation is to keep things private unless reveled. So what would be a better pattern?
var module = (function($, window, document, undefined) {
return {
subModuleA : (function() {
var privateA = 100;
return {
// We have access to privateA
publicA_1 : function() {
console.log(privateA);
// How do I use a method from publicB_1
// the only way is:
module.subModuleB.publicB_2();
// but I don't want to use "module"
},
publicA_2 : function() {
console.log(privateA);
}
}
})(),
subModuleB : (function() {
var privateB = 250;
return {
// We have access to privateB
publicB_1 : function() {
console.log(privateB);
},
publicB_2 : function() {
console.log(privateB);
// I have access to publicB_1
this.publicB_1();
}
}
})()
}
})(jQuery, window, document);
What you actually have is an issue with dependencies. Sub module A has a dependency on Sub module B. There are two solutions that come to mind.
Define both modules as their own variables inside the function closure, but return them together in a single object.
What you actually want is instantiable classes where Class A has a dependency on Class B.
Since solution #1 is the closest to your current code, let's explore that first.
Define Both Modules Separately Inside the Closure
var module = (function($, window, document, undefined) {
var SubModuleA = function() {
var privateA = 100;
return {
// We have access to privateA
publicA_1 : function() {
console.log(privateA);
// Refer to SubModuleB via the private reference inside your "namespace"
SubModuleB.publicB_2();
// but I don't want to use "module"
},
publicA_2 : function() {
console.log(privateA);
}
};
}();
var SubModuleB = function() {
var privateB = 250;
return {
// We have access to privateB
publicB_1 : function() {
console.log(privateB);
},
publicB_2 : function() {
console.log(privateB);
// I have access to publicB_1
this.publicB_1();
}
};
}();
// Return your module with two sub modules
return {
subModuleA : SubModuleA,
subModuleB : SubModuleB
};
})(jQuery, window, document);
This allows you to refer to your two sub modules using local variables to your module's closure (SubModuleA and SubModuleB). The global context can still refer to them as module.subModuleA and module.subModuleB.
If Sub Module A uses Sub Module B, it begs the question of whether or not Sub Module B needs to be revealed to the global context at all.
To be honest, this is breaking encapsulation because not all the functionality of Sub Module A exists in Sub Module A. In fact, Sub Module A cannot function correctly without Sub Module B.
Given your particular case, the Module Pattern seems to be an Anti Pattern, that is, you are using the wrong tool for the job. In reality, you have two classifications of objects that are interdependent. I would argue that you need "classes" (JavaScript Constructor functions) and traditional OOP practices.
Use JavaScript Constructor Functions ("classes")
First, let's refactor your "module" into two classes:
var module = (function($, window, document, undefined) {
function ClassA(objectB) {
var privateA = 100;
this.publicA_1 = function() {
console.log(privateA);
objectB.publicB_2();
};
this.publicA_2 = function() {
console.log(privateA);
};
}
function ClassB() {
var privateB = 250;
this.publicB_1 = function() {
console.log(privateB);
};
this.publicB_2 = function() {
console.log(privateB);
this.publicB_1();
};
}
// Return your module with two "classes"
return {
ClassA: ClassA,
ClassB: ClassB
};
})(jQuery, window, document);
Now in order to use these classes, you need some code to generate the objects from the constructor functions:
var objectA = new module.ClassA(new module.ClassB());
objectA.publicA_1();
objectA.publicA_2();
This maximizes code reuse, and because you are passing an instance of module.ClassB into the constructor of module.ClassA, you are decoupling those classes from one another. If you don't want outside code to be managing dependencies, you can always tweak ClassA thusly:
function ClassA() {
var privateA = 100,
objectB = new ClassB();
this.publicA_1 = function() {
console.log(privateA);
objectB.publicB_2();
};
this.publicA_2 = function() {
console.log(privateA);
};
}
Now you can refer to module.ClassB using the name within the function closure: ClassB. The advantage here is that outside code does not have to give module.ClassA all of its dependencies, but the disadvantage is that you still have ClassA and ClassB coupled to one another.
Again, this begs the question of whether or not the global context needs ClassB revealed to it.

Loading classes dynamically in Dart

So, I looked into mirror and they might be an option, but given their async nature they might be really awkward to use or just not viable in the long run. Since they are currently not supported (just a play-thing) they are not really viable at this time anyway.
Question: Given a series of Strings, eg. [ "Foo", "Bar" ] a base class Application and Widget in library corelib; and a corresponding class for each of the strings FooWidget, BarWidget in library applibrary;, what's currently the most elegant method to get Application to turn the strings into instances of the corresponding classes, that works with dart2js.
Equivalent PHP pseudo-example for clarity,
<?php # example
namespace corelib;
class Widget {
function name() {
return \get_called_class();
}
}
class Application {
static function resolve($name, $library) {
$class = $library.'\\'.$name.'Widget';
return new $class;
}
}
namespace applibrary;
class FooWidget extends \corelib\Widget {
// ...
}
class BarWidget extends \corelib\Widget {
// ...
}
$foowidget = \corelib\Application::resolve('Foo', 'applibrary');
$barwidget = \corelib\Application::resolve('Bar', 'applibrary');
echo "{$foowidget->name()} <br> {$barwidget->name()}";
Output
applibrary\FooWidget
applibrary\BarWidget
If you can validate the list of strings, then the best way for the moment (until mirror support in dart2js becomes better baked), is likely an if statement.
// toy implementation
Widget getWidget(name) {
switch (name) {
case "Foo": return new FooWidget();
case "Bar": return new FooWidget();
default: // handle error
}
}
// elsewhere:
var fooWidget = getWidget("Foo");
var barWidget = getWidget("Bar");
The list of xyzWidget classes will be a finite list (as you can't dynamically link in code at runtime anyway).
Of course, a more elegant implementation is to use mirrors (shown below, for reference, although it doesn't currently fulfil the dar2js criteria)
Future<Widget> getWidget(library, name) {
var completer = new Completer<Widget>();
MirrorSystem ms = currentMirrorSystem();
ClassMirror cm = ms.libraries[library].classes[name];
// instantiate an instance of the class
cm.newInstance(null,[]).then((instance) => completer.complete(instance));
return completer.future;
}
// elsewhere:
getWidget("applibrary","FooWidget").then((Widget widget) {
// do something with widget
});

Resources