How do you get all instances of a Template? - meteor

I know I can get a single template instance by doing Blaze.getView(node). But how can I find all instances of Template.foo?

If we borrow walkTheDOM from Crockford, we can drop this into the browser console and find all template instances on any page
function findAllTemplateInstances(templateName){
function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
var instances = [];
walkTheDOM(document.body, function(node) {
try{
if (Blaze.getView(node).name === templateName){
instances.push(Blaze.getView(node).templateInstance());
}
} catch(err){
}
});
return _.uniq(instances)
}

Related

Issue with coroutines fold function and Firestore

thank you for taking your time to read my problem.
Im currently using Firebase Firestore to retrieve a list of objects that I which to display to the UI, im trying to use a suspend function to fold the accumulative values of a sequence of calls from the Firestore server, but at the moment im unable to pass the result value outside the scope of the coroutine.
This is my fold function:
suspend fun getFormattedList(): FirestoreState {
return foldFunctions(FirestoreModel(""), ::getMatchesFromBackend, ...., ....)
}
This is my custom fold function:
suspend fun foldFunctions(model: FirestoreModel,
vararg functions: suspend (FirestoreModel, SuccessData) -> FirestoreState): FirestoreState {
val successData: SuccessData = functions.fold(SuccessData()) { updatedSuccessData, function ->
val status = function(model, updatedSuccessData)
if (status !is FirestoreState.Continue) {
return status
}
updatedSuccessData <--- I managed to retrieve the list of values correctly here
}
val successModel = SuccessData()
successData.matchList?.let { successModel.matchList = it }
successData.usermatchList?.let { successModel.usermatchList = it }
successData.formattedList?.let { successModel.formattedList = it }
return FirestoreState.Success(successModel) <--- I cant event get to this line with debugger on
}
This is my first function (which is working fine)
suspend fun getMatchesFromBackend(model: FirestoreModel, successData: SuccessData): FirestoreState {
return try {
val querySnapshot: QuerySnapshot? = db.collection("matches").get().await()
querySnapshot?.toObjects(Match::class.java).let { list ->
val matchList = mutableListOf<Match>()
list?.let {
for (document in it) {
matchList.add(Match(document.away_score,
document.away_team,
document.date,
document.home_score,
document.home_team,
document.match_id,
document.matchpoints,
document.played,
document.round,
document.tournament))
}
successData.matchList = matchList <--- where list gets stored
}
}
FirestoreState.Continue
} catch (e : Exception){
when (e) {
is RuntimeException -> FirestoreState.MatchesFailure
is ConnectException -> FirestoreState.MatchesFailure
is CancellationException -> FirestoreState.MatchesFailure
else -> FirestoreState.MatchesFailure
}
}
}
My hypothesis is that the suspen fun get cancelled and the continuation of the scope gets blocked, I have tried to use runBlocking { } without vail. If someone has an idea of how to circumvent this issue I'd be very gratefull.

TornadoFX:proper way to bind model

I was taking a look at this :
tornadofx
and tried to expand on it with database connection and little more options, (not all of them make sense, but its just playing in a sandbox).
Even though table can be directly edited and the data will persist in database, i did try to do edit through text fields too. actual table editing would happen through different view and not table itself, as i said its just example.
Database used is Jetbrains Exposed.
object Categories : IntIdTable() {
val name = varchar("name", 64).uniqueIndex()
val description = varchar("description", 128)
}
class Category(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<Category>(Categories)
var name by Categories.name
var description by Categories.description
override fun toString(): String {
return "Category(name=\"$name\", description=\"$description\")"
}
}
now controller looks something like this, functions are just rudimentary and picked as an example.
typealias ModelToDirtyState = Map.Entry<CategoryModel, TableColumnDirtyState<CategoryModel>>
class CategoryModel() : ItemViewModel<Category>() {
val name: SimpleStringProperty = bind(Category::name)
val description: SimpleStringProperty = bind(Category::description)
}
class DBController : Controller() {
val categories: ObservableList<CategoryModel> by lazy {
transaction {
SchemaUtils.create(Categories)
Category.all().map {
CategoryModel().apply {
item = it
}
}.observable()
}
}
init {
Database.connect(
"jdbc:mysql://localhost:3306/test", driver = "com.mysql.cj.jdbc.Driver",
user = "test", password = "test"
)
TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
}
fun deleteCategory(model: CategoryModel) {
runAsync {
transaction {
model.item.delete()
}
}
categories.remove(model)
}
fun updateCategory(model: CategoryModel) {
transaction {
Categories.update {
model.commit()
}
}
}
fun commitDirty(modelDirtyMappings: Sequence<ModelToDirtyState>) {
transaction {
modelDirtyMappings.filter { it.value.isDirty }.forEach {
it.key.commit()
println(it.key)// commit value to database
it.value.commit() // clear dirty state
}
}
}
Just to quickly comment on controller, delete method works as "intended" however the update one does not, it does not work in sense that after using delete item is remove both from database and tableview(underlying list) itself, and when i do update its not, now i know the reason, i call remove manually on both database and list, now for update perhaps i could do change listener, or maybe tornadofx can do this for me, i just cant set it up to do it. Following code will make things clearer i think.
class CategoryEditor : View("Categories") {
val categoryModel: CategoryModel by inject()
val dbController: DBController by inject()
var categoryTable: TableViewEditModel<CategoryModel> by singleAssign()
var categories: ObservableList<CategoryModel> by singleAssign()
override val root = borderpane {
categories = dbController.categories
center = vbox {
buttonbar {
button("Commit") {
action {
dbController.commitDirty(categoryTable.items.asSequence())
}
}
button("Roll;back") {
action {
categoryTable.rollback()
}
}
// This model only works when i use categorytable.tableview.selected item, if i use categoryModel, list gets updated but not the view itself
// Question #1 how to use just categoryModel variable without need to use categorytable.tableview.selecteditem
button("Delete ") {
action {
val model = categoryTable.tableView.selectedItem
when (model) {
null -> return#action
else -> dbController.deleteCategory(model)
}
}
}
//And here no matter what i did i could not make the view update
button("Update") {
action {
when (categoryModel) {
null -> return#action
else -> dbController.updateCategory(categoryModel)
}
categoryTable.tableView.refresh()
}
}
}
tableview<CategoryModel> {
categoryTable = editModel
items = categories
enableCellEditing()
enableDirtyTracking()
onUserSelect() {
//open a dialog
}
//DOES WORK
categoryModel.rebindOnChange(this) { selectedItem ->
item = selectedItem?.item ?: CategoryModel().item
}
// Question #2. why bindSelected does not work, and i have to do it like above
//DOES NOT WORK
// bindSelected(categoryModel)
//
column("Name", CategoryModel::name).makeEditable()
column("Description", CategoryModel::description).makeEditable()
}
}
right = form {
fieldset {
field("Name") {
textfield(categoryModel.name)
}
}
fieldset {
field("Description") {
textfield(categoryModel.description)
}
}
button("ADD CATEGORY") {
action {
dbController.addCategory(categoryModel.name.value, categoryModel.description.value)
}
}
}
}
}
I apologize for huge amount of code, also in last code snipped i left questions in form of comments where i fail to achive desired results.
I am sure i am not properly binding code, i just dont see why, also i sometimes use one variable to update data, my declared one "categoryModel" and sometimes i use tableview.selecteditem, it just seems hacky and i cant seem to grasp way.
Thank you!

HERE-SDK lite drag marker in MapView

I am just trying out the SDK Lite API and I am wondering how I can achieve to drag a MapMarker object from one place to another. I suggest, it works somehow with disabling the default onPan gesture, but actually the problem starts with picking an existing object.
Here is my code so far:
public void pickMarker(Point2D p) {
map.getGestures().disableDefaultAction(GestureType.PAN);
map.pickMapItems(p, 20f, pickMapItemsResult -> {
if (pickMapItemsResult != null) {
pickedMarker = pickMapItemsResult.getTopmostMarker();
} else {
map.getGestures().enableDefaultAction(GestureType.PAN);
}
});
}
public void dragMarker(Point2D p) {
if (pickedMarker != null) {
pickedMarker.setCoordinates(map.getCamera().viewToGeoCoordinates(p));
}
}
public boolean releaseMarker(Point2D p) {
map.getGestures().enableDefaultAction(GestureType.PAN);
if (pickedMarker != null) {
GeoCoordinates newCoordinates = map.getCamera().viewToGeoCoordinates(p);
pickedMarker.setCoordinates(newCoordinates);
pickedMarker = null;
return true;
}
return false;
}
while these functions are called on the three states of the onPanListener:
mapView.getGestures().setPanListener((gestureState, point2D, point2DUpdate, v) -> {
if (gestureState.equals(GestureState.BEGIN)) {
mapViewUIEngine.pickMarker(point2D);
}
if (gestureState.equals(GestureState.UPDATE)) {
mapViewUIEngine.dragMarker(point2DUpdate);
}
if (gestureState.equals(GestureState.END)) {
if (mapViewUIEngine.releaseMarker(point2DUpdate)) {
regionController.movePoint(0,
updateNewLocation(point2D, point2DUpdate);
}
}
});
From one of the developer in Github I now know, that the polygon is returned instead of the marker (which is lying on a polygon line, but how can I get the marker instead?
You can use map markers to precisely point to a location on the map.
The following method will add a custom map marker to the map:
MapImage mapImage = MapImageFactory.fromResource(context.getResources(), R.drawable.here_car);
MapMarker mapMarker = new MapMarker(geoCoordinates);
mapMarker.addImage(mapImage, new MapMarkerImageStyle());
mapView.getMapScene().addMapMarker(mapMarker);
For more details, please refer
https://developer.here.com/documentation/android-sdk/dev_guide/topics/map-items.html#add-map-markers

Hook for Template.rendered except in this case, I want it to be called for every rendered event

How can I call a function, or run some code for when any and every Template.rendered event is called in Meteor? (Not just a specific template)
(Is there a way I can do this without overloading meteor's base functions?)
Thanks!
One way is to call another method:
dothis = function() {
// Something
}
Template.hello.rendered = function() {
dothis();
}
Template.hello2.rendered = function() {
dothis();
}
If you have nothing else to do in your rendered you could:
Template.hello2.rendered = dothis;
Also in bulk (will override any other rendered if it is defined before, when it is run):
for(tmpl in Template) {
Template[tmpl].rendered = dothis;
};
(and also if you have defined stuff before you can make it run both callbacks:)
for(tmpl in Template) {
if(Template[tmpl].rendered) {
Template[tmpl].rendered = function() {
var originalfunction = Template[tmpl].rendered;
var result = originalfunction.apply(this);
dothis.apply(this);
return result;
}
}
else
{
Template[tmpl].rendered = dothis;
}
};

how to make consecutive DWR calls within sub process

Hi i want to make nested dwr call.
In my java code i have two function
public String getNetworks() {
// return some networks.
}
public String getInternalNetwork(network) {
// return some networks.
}
I want to make a chained dwr call.
myDwr.getNetworks({
callback: function() {
var network
/// parse out answer.
myDwr.getInternalNetwork(network, {
callback:function() {
});
}
});
how do i do this so that dwr calls are made in order, and both functions are executed.
my answer was to store the network in a different call.
DWREngine.beginBatch();
myDwr.getNetworks({
callback: function(networks) {
network = getMainNetwork(networks);
}
});
myDwr.getInternalNetwork(network, {
callback: function() {
}
});
DWREngine.endBatch();

Resources