Sencha Touch 2 store is loaded multiple time [Maximum call stack size exceeded] - sencha-touch-2

I'm having a weird problem with the Sencha Touch 2 Store class. Here is what I have:
A simple view PollsList that defines a list view (with a store attribute set to Polls). I've included the required store as follow: requires:['Polls'],
A store class Polls with a model attribute set to Poll and a dummy data attribute,
A model class named Poll (the simplest possible),
An app.js file with the following launch methode:
var pollsListView = Ext.create('PollsList');
Ext.Viewport.add(pollsListView);
Ext.Viewport.setActiveItem(pollsListView);
I've also included the stores: ['Polls'] declaration in the app.js as required.
Now, the weird thing is when I access the PollsList view, the Poll store is being loaded indefinitely, till I got a the following error:
Uncaught RangeError: Maximum call stack size exceeded sencha-touch.js:598
And the stack seems to loop on the following calls:
Ext.ClassManager.instantiate sencha-touch.js:6378
(anonymous function) sencha-touch.js:3198
(anonymous function) app/store/Polls.js:4
Ext.apply.globalEval sencha-touch.js:598
Ext.apply.globalEval sencha-touch.js:599
Ext.apply.loadScriptFile sencha-touch.js:7673
Ext.apply.require sencha-touch.js:7831
Ext.apply.syncRequire sencha-touch.js:7695
(anonymous function)
Any idea?

Seems weird, done many a times, but did not went wrong.
Any ways, try removing the setActiveItem as there is only one view and it will take it as active.
Remove the require line from the code, as it seems that currently it is not required though.(Just because i want to make this sample running).
Now, try initializing the store, as
var store = Ext.create("YourStore") //
var listControl = Ext.craeate("YourList" ,{store : "aboveCreatedStore" , ..... });
listControl.setData( {name :'hello'} ); // hoping the model is having one String type field
Ext.ViewPort.add(listControl);
Thats it...
The above given code is not a complete solution(its like a patch), but it is to make you know what wrong you are doing in your current code.

Related

Raku Cro service subscribing to data "in the background" general guidance

I am attempting to put together a Cro service that has a react/whenever block consuming data "in the background" So unlike many examples of websocket usage with Cro, this has nothing to do with routes that may be accessed via the browser.
My use case is to consume message received via an MQTT topic and do some processing with them. At a later stage in development I might create a supply out of this data, but for now, when data is received it will be stored in a variable and dependant on certain conditions, be sent to another service via a http post.
My thought was to include a provider() in the Cro::HTTP::Server setup like so:
use Cro::HTTP::Log::File;
use Cro::HTTP::Server;
use Routes;
use DataProvider; # Here
my Cro::Service $http = Cro::HTTP::Server.new(
http => <1.1>,
host => ...,
port => ...,
application => [routes(), provider()], # Made this into an array of subs?
after => [
Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR)
]
);
And in the DataProvider.pm6:
use MQTT::Client;
sub provider() is export {
my $mqtt = MQTT::Client.new: server => 'localhost';
react {
whenever $mqtt.subscribe('some/mqtt/topic') {
say "+ topic: { .<topic> } => { .<message>.decode("utf8-c8") }";
}
}
}
This throws a bunch of errors:
A react block:
in sub provider at DataProvider.pm6 (DataProvider) line 5
in block <unit> at service.p6 line 26
Died because of the exception:
Invocant of method 'write' must be an object instance of type
'IO::Socket::Async', not a type object of type 'IO::Socket::Async'. Did
you forget a '.new'?
in method subscribe at /home/cam/raku/share/perl6/site/sources/42C762836A951A1C11586214B78AD34262EC465F (MQTT::Client) line 133
in sub provider at DataProvider.pm6 (DataProvider) line 6
in block <unit> at service.p6 line 26
To be perfectly honest, I am totally guessing that this is how I would approach the need to subscribe to data in the background of a Cro service, but I was not able to find any information on what might be considered the recommended approach.
Initially I had my react/whenever block in the main service.pm6 file, but that did not seem right. And needed to be wrapped in a start{} block because as I have just learned, react is blocking :) and cro was not able to actually start.
But following the pattern of how Routes are implemented seemed logical, but I am missing something. The error speaks about setting up a new method, but I'm not convinced that is the root cause. Routes.pm6 does not have a constructor.
Can anyone point me in the right direction please?
Thanks to all who have provided information, this has been a very valuable learning exercise.
The approach of passing additional sub routines, along side router() in the application parameter to Cro::HTTP::Server.new gave further trouble. (an array is not allowed, and broke routing)
Instead, I have moved the background work into a class of it's own, and given it a start and stop method more akin to Cro::HTTP::Server.
My new approach:
service.pm6
use Cro::HTTP::Log::File;
use Cro::HTTP::Server;
use Routes;
use KlineDataSubscriber; # Moved mqtt functionality here
use Database;
my $dsn = "host=localhost port=5432 dbname=act user=.. password=..";
my $dbh = Database.new :$dsn;
my $mqtt-host = 'localhost';
my $subscriber = KlineDataSubscriber.new :$mqtt-host;
$subscriber.start; # Inspired by $http.start below
my Cro::Service $http = Cro::HTTP::Server.new(
http => <1.1>,
host => ...,
port => ...,
application => routes($dbh), # Basically back the way it was originally
after => [
Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR)
]
);
$http.start;
say "Listening at...";
react {
whenever signal(SIGINT) {
say "Shutting down...";
$subscriber.stop;
$http.stop;
done;
}
}
And in KlineDataSubscriber.pm6
use MQTT::Client;
class KlineDataSubscriber {
has Str $.mqtt-host is required;
has MQTT::Client $.mqtt = Nil;
submethod TWEAK() {
$!mqtt = MQTT::Client.new: server => $!mqtt-host;
await $!mqtt.connect;
}
method start(Str $topic = 'act/feed/exchange/binance/kline-closed/+/json') {
start {
react {
whenever $!mqtt.subscribe($topic) {
say "+ topic: { .<topic> } => { .<message>.decode("utf8-c8") }";
}
}
}
}
method stop() {
# TODO Figure how to unsubscribe and cleanup nicely
}
}
This feels much more "Cro idiomatic" to me, but I would be happy to be corrected.
More importantly, it works as expected and I feel is somewhat future proof. I should be able to create a supply to make real-time data available to the router, and push data to any connected web clients.
I also intend to have a http GET endpoint /status with various checks to ensure everything healthy
The root cause
The error speaks about setting up a new method, but I'm not convinced that is the root cause.
It's not about setting up a new method. It's about a value that should be defined instead being undefined. That typically means a failure to attempt to initialize it, which typically means a failure to call .new.
Can anyone point me in the right direction please?
Hopefully this question helps.
Finding information on a recommended approach
I am totally guessing that this is how I would approach the need to subscribe to data in the background of a Cro service, but I was not able to find any information on what might be considered the recommended approach.
It might be helpful for you to list which of the get-up-to-speed steps you've followed from Getting started with Cro, including the basics but also the "Learn about" steps at the end.
The error message
A react block:
in sub provider ...
Died because of the exception:
...
in method subscribe ...
The error message begins with the built in react construct reporting that it caught an exception (and handled it by throwing its own exception in response). A "backtrace" corresponding to where the react appeared in your code is provided indented from the initial "A react block:".
The error message continues with the react construct summarizing its own exception (Died because ...) and explains itself by reporting the original exception, further indented, in subsequent lines. This includes another backtrace, this time one corresponding to the original exception, which will likely have occurred on a different thread with a different callstack.
(All of Raku's structured multithreading constructs[1] use this two part error reporting approach for exceptions they catch and handle by throwing another exception.)
The first backtrace indicates the react line:
in sub provider at DataProvider.pm6 (DataProvider) line 5
use MQTT::Client;
sub provider() is export {
my $mqtt = MQTT::Client.new: server => 'localhost';
react {
The second backtrace is about the original exception:
Invocant of method 'write' must be an object instance of type
'IO::Socket::Async', not a type object of type 'IO::Socket::Async'. ...
in method subscribe at ... (MQTT::Client) line 133
This reports that the write method called on line 133 of MQTT::Client requires its invocant is an instance of type 'IO::Socket::Async'. The value it got was of that type but was not an instance, but instead a "type object". (All values of non-native types are either type objects or instances of their type.).
The error message concludes with:
Did you forget a '.new'?
This is a succinct hint based on the reality that 99 times out of a hundred the reason a type object is encountered when an instance is required is that code has failed to initialize a variable. (One of the things type objects are used for is to serve the role of "undefined" in languages like Perl.)
So, can you see why something that should have been an initialized instance of 'IO::Socket::Async' is instead an uninitialized one?
Footnotes
[1] Raku's constructs for parallelism, concurrency, and asynchrony follow the structured programming paradigm. See Parallelism, Concurrency, and Asynchrony in Raku for Jonathan Worthington's video presentation of this overall approach. Structured constructs like react can cleanly observe, contain, and manage events that occur anywhere within their execution scope, including errors such as error exceptions, even if they happen on other threads.
You seem to be fine now but when I first saw this I made this https://github.com/jonathanstowe/Cro-MQTT which turns the MQTT client into a first class Cro service.
I haven't released it yet but it may be instructive.

Dynamic model attribute with SAILSJS

My use case needs me to use Dynamic Model attributes with my Sails.Js project and all of my methods fail. First I tried to call model1 method from model2 but it doesn't works. I also tried to use global variables but this fails too because, the global is set after the load of the application, and finaly I called model1Controller from the model2 but it still not working.
This is the mothod in my model2Controller
getbyTable:function(req,res){
let field = Field.find({fTable:req.param('tableName')});
field.exec(function(err, response) {
if(err) {
res.status(500);
return res.view('500', {data: err});
}
//res.json(response);
return response;
});
},
And this is my model2
'use strict';
const fieldController = require('../controllers/Model1Controller');
const donnees = fieldController.getbyTable('person');
module.exports={
}
When run it fires as error that req.param is not a function.
Need help!!! Thanks.
This looks like an interesting way to organize - I'd be curious to see how successful a project could be without Model attributes set in stone.
I can see a few specific errors in your code, maybe seeing them will help you move forward.
From your model2 you invoke getbyTable('person') with a string argument - but all controller methods are really intended to have reqest/response arguments (as in the definition getbyTable(req, res). Directly invoking a controller method is a bit unusual - if you ever did it, I'd expect to pass along a request and response from some other controller method.
Inside getbyTable, you try to return the response, but the response is only defined inside the exec callback. The response would be an array of objects fetched from your database - if that's what you need, you can't return them directly since database calls are async.
Your controller should probably do something with res in all logical branches, such as res.json, res.send, etc.
It's a bit hard to see exactly what you're trying to achieve, so maybe if you could explain the goal I could have some more relevant advice. For now, I could say that you might want to consider putting some code inside a service rather than a controller. Create file /api/services/MyService.js and use it to export a method that can be called from your model2 (you can require the service just like the controller). Keep the controller methods strictly for handling requests.
Good luck.

qooxdoo new property not visible in log tool

I am checking an instance of a qooxdoo class using console.log('%o', inst).
Here the properties are shown with leading "$$user..." marks.
But when adding a new property to the class, it is not shown in the console.log-output.
The code is running using the new property; so the syntax and class structure is ok. I checked in release and debug mode.
What do I have to do to see the new property also in the console.log output ?
Or is there something cached so it will not be shown until a certain refresh ?
Qooxdoo uses $$user_ to store the current, user provided, property value. The $$user_ values are only set if the property has been actively set after the object properties are constructed during class initialization.
Having some kind of init value is not enough, so you've to put something in there actively to make them visible in the console.log call above.
The init values are stored in the prototype as $$init_ followed by the variable name. So
qx.Class.define("foobar", {
extend: qx.core.Object,
properties: {
test1 : {},
test2 : {init: 5}
}
});
will result in no single $$user_test1 or $$user_test2 directly after you initialized the class. If you call setTest2(99), you'll see that $$user_test2 shows up in the console - and it disappears if you call resetTest2().
To answer the question: you can only enforce having $$user_ values to be set, by putting someting in actively. Or better define a watch in your chrome console that calls getTest2() on the watched object.

JSONStore errors - PROVISION_TABLE_SEARCH_FIELDS_MISMATCH or USERNAME_MISMATCH_DETECTED

We are interrogating the JSONStore (in a JS app) on a regular bases using the setInterval function and from time to time (i.e. cannot reproduce it) we get the errors PROVISION_TABLE_SEARCH_FIELDS_MISMATCH or USERNAME_MISMATCH_DETECTED.
The problem is that I never change the search fields or the username (as they are hardcoded).
Is there any reason that these errors are returned?
You can review the following list of JSONStore error codes: https://www-01.ibm.com/support/knowledgecenter/SSZH4A_6.1.0/com.ibm.worklight.dev.doc/devref/r_jsonstore_errorcodes.html
-2 PROVISION_TABLE_SEARCH_FIELDS_MISMATCH
Search fields are not dynamic. It is not possible to change search fields without calling the destroy method or the removeCollection method in the WL.JSONStore class before calling the init method with the new search fields. This error can occur if you change the name or type of the search field. For example: {key: 'string'} to {key: 'number'} or {myKey: 'string'} to {theKey: 'string'}.
and
-6 USERNAME_MISMATCH_DETECTED
To log out, a JSONStore user must call the closeAll method in the WL.JSONStore class first. There can be only one user at a time.
My guess is that you may want to increase the timeout value you're using. This does suspiciously sound like a timing issue (you also say that it occurs from "time to time").

Ninject: More than one matching bindings are available

I have a dependency with parameters constructor. When I call the action more than 1x, it show this error:
Error activating IValidationPurchaseService
More than one matching bindings are available.
Activation path:
1) Request for IValidationPurchaseService
Suggestions:
1) Ensure that you have defined a binding for IValidationPurchaseService only once.
public ActionResult Detalhes(string regionUrl, string discountUrl, DetalhesModel detalhesModel)
{
var validationPurchaseDTO = new ValidationPurchaseDTO {...}
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
...
}
I'm not sure what are you trying to achieve by the code you cited. The error is raised because you bind the same service more than once, so when you are trying to resolve it it can't choose one (identical) binding over another. This is not how DI Container is supposed to be operated. In your example you are not getting advantage of your DI at all. You can replace your code:
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
With this:
this.ValidationPurchaseService = new ValidationPurchaseService(validationPurchaseDTO:validationPurchaseDTO, confirmPayment:true)
If you could explain what you are trying to achieve by using ninject in this scenario the community will be able to assist further.
Your KernelFactory probably returns the same kernel (singleton) on each successive call to the controller. Which is why you add a similar binding every time you hit the URL that activates this controller. So it probably works the first time and starts failing after the second time.