How can I check if a handler exists in backbone.radio? - backbone.js

I am switching my backbone.wreqr library in favor of backbone.radio
My code base uses extensibly the functions
const channel = wreqr.radio.channel("name")
channel.reqres.hasHandler("name")
channel.reqres.getHandler("name")
Though it seems there isn't a direct equivalent version of hasHandler and getHandler in radio.

Couldn't you just check for the type of the handler?
const channel = Radio.channel('name');
channel.on('mymethod', this.mymethod); // returns this.mymethod without executing it
const myhandler = channel.request('mymethod');
if (typeof myhandler !== 'undefined') myhandler();

Related

How to properly deal with code that need to wait for previous constants to be loaded?

Here is a change to a long code before a render that wasted me time to correct many lines in the code:
Before:
const my_model:MyModel = JSON.parse(localStorage.getItem('my_model')!)
const my_positions:MyModel = JSON.parse(localStorage.getItem('my_positions')!)
After:
const waitformyIcm:Boolean = useDetailMyModelQuery(paramid.id).isSuccess;
const myIcm:undefined | MyModel| any = useDetailMyModelQuery(paramid.id).data
const waitforpositions:Boolean = usePatternPositionsPerModelQuery(paramid.icm).isSuccess;
const positions:undefined | PatternPositions[] = usePatternPositionsPerModelQuery(paramid.icm).data
The consequence is that for almost all the next constants I needed to let the program wait until those first lines completed loading. My question is how to cope with such situations because I feel my approach was not as it should:
For example this previous line would already cause crashes:
const harvestAfter:number[] = [myIcm.length_period1, myIcm.length_period2, myIcm.length_period3]
This was solved by:
const harvestAfter:number[] = waitformyIcm && [myIcm.length_period1, myIcm.length_period2, myIcm.length_period3]
Another challenge was to set a default state with data that had to be loaded first. I solved that with:
const [myFilters, setMyFilters] = useState(myfilters);
useEffect(() => setMyFilters(myfilters), [myfilters && waitforpositions]);
How to properly deal with code that need to wait for previous constants to be loaded in REACT?
Using myconst && ......?
Using useEffect?
Using useRef?
Using async await (how to do that for declaring constants)
Other?
Please don't call the same hook multiple times, that is just a waste of user memory and CPU time. (These hooks are doing work internally and you invoke them twice for no good reason.)
Just don't annotate the types here and assign them to a variable. They are already 100% typesafe from the hook.
Then, use skip:
const icmResult = useDetailMyModelQuery(paramid.id);
const patternsResult = usePatternPositionsPerModelQuery(paramid.icm, { skip: !icmResult.isSuccess });
As for the variable assignment, you could also use destructuring although I don't really see the point:
const { isSuccess: waitformyIcm, data: myIcm } = useDetailMyModelQuery(paramid.id);
As for a default state, there are many approaches. If it is an object you define inline, it would be a new reference on every render, so you best useMemo to get around that:
const filtersWithDefaults = useMemo(() => filters ?? defaultFilters, [filters])

How to access methods from array element?

I've recently taken upon myself to add setter and getter methods to my class.
Since doing this, many parts of my code got broken and I'm unable to access getter methods.
Take the example below:
private loadInputs() : Input[] {
var inputs = <Input[]>this.get('inputs');
inputs.sort((a,b) => a.QuoteRef().localeCompare(b.QuoteRef()))
return( inputs || [] );
}
My input class has 2 variables,
_Project: string
_line: string
Which I access using a method QuoteRef()
public QuoteRef(): string {
return this._Project.concat('-' + this._Line.toString().padStart(3,'0'));
}
Whenever I try to access a method or a getter from my class on an item that is casted as an Input, I can see the variables (though not access them as they are private), but the prototype section doesn't contain any of the methods.
This triggers the following error in the website console:
TypeError: a.QuoteRef is not a function
What am I doing wrong?
Update
I got it to work by updating the code as follows:
inputs.sort((a,b) => {
let first = new Input(a);
let second = new Input(b);
return first.QuoteRef().localeCompare(second.QuoteRef());
});
Without seeing your complete class I can only guess, but I think that a and b in your sort are not of the type you expect. I can't see what this.get('inputs') does, but I suspect it is not returning an array with Input class objects. Hence the function cannot be found (is not a function). You could try:
inputs.sort((a,b) => {
console.log(typeof a);
console.log(typeof b);
a.QuoteRef().localeCompare(b.QuoteRef());
})
and check what the type is. Then check what your this.get actually returns.
Edit: forgot to mention that your IDE probably does not warn you because you cast the output of this.get to <Input[]>.

How can I use Tokio to trigger a function every period or interval in seconds?

In Node.js I can set the interval that a certain event should be triggered,
function intervalFunc() {
console.log('whelp, triggered again!');
}
setInterval(intervalFunc, 1500);
However the interface for Tokio's interval is a bit more complex. It seems to be a something to do with a much more literal definition of an interval, and rather than calling a function at an interval, it simply stalls the thread until the time passes (with .await).
Is there a primitive in Tokio that calls a function "every x seconds" or the like? If not, is there an idiom that has emerged to do this?
I only need to run one function on a recurring interval... I don't care about other threads either. It's just one function on Tokio's event loop.
Spawn a Tokio task to do something forever:
use std::time::Duration;
use tokio::{task, time}; // 1.3.0
#[tokio::main]
async fn main() {
let forever = task::spawn(async {
let mut interval = time::interval(Duration::from_millis(10));
loop {
interval.tick().await;
do_something().await;
}
});
forever.await;
}
You can also use tokio::time::interval to create a value that you can tick repeatedly. Perform the tick and call your function inside of the body of stream::unfold to create a stream:
use futures::{stream, StreamExt}; // 0.3.13
use std::time::{Duration, Instant};
use tokio::time; // 1.3.0
#[tokio::main]
async fn main() {
let interval = time::interval(Duration::from_millis(10));
let forever = stream::unfold(interval, |mut interval| async {
interval.tick().await;
do_something().await;
Some(((), interval))
});
let now = Instant::now();
forever.for_each(|_| async {}).await;
}
async fn do_something() {
eprintln!("do_something");
}
See also:
How can I run a set of functions concurrently on a recurring interval without running the same function at the same time using Tokio?
I am still a rust/tokio beginner, but I did find this solution helpful for myself:
use std::time::Duration;
use tokio::time;
use tokio_stream::wrappers::IntervalStream;
#[tokio::main]
async fn main() {
let mut stream = IntervalStream::new(time::interval(Duration::from_secs(1)));
while let Some(_ts) = stream.next().await {
println!("whelp, triggered again!");
}
}
Please note that _ts holds the execution timestamp.

How do parameters work in C callback functions

I'm reading some freeRTOS code, and I'm not understanding how a function callbacks work. Take this example. The following function is defined -
static void prov_event_handler(void *user_data,
wifi_prov_cb_event_t event, void *event_data)
{
switch (event) {
case WIFI_PROV_CRED_RECV: {
wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)event_data;
...
}
This is the callback function that we want to call from this code:
/* Configuration for the provisioning manager */
wifi_prov_mgr_config_t config = {
.scheme = wifi_prov_scheme_ble,
.scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM,
.app_event_handler = {
.event_cb = prov_event_handler,
.user_data = NULL
}
};
ESP_ERROR_CHECK(wifi_prov_mgr_init(config));
So far, so good. Where I am confused is where the heck do the parameters come from? When prov_event_handler is run, it has values for event_data. How does this generally work?
Thanks.

Detecting Guild ID

I want to make certain commands so they can only be used in a specific guild.
I've tried an if statement that checks if message.guild.id = the guild id, but the command still will execute in any guild, perhaps I'm doing something wrong.
client.on("message", msg => {
var bcid = "585676550544949248"
if (msg.guild.id = bcid) {
if (msg.content.toLowerCase().startsWith(prefix + "ping")) {
msg.channel.send("Pong! :ping_pong:");
}
}
});
One = symbol is used for assigning a value to a variable, two == or three = symbols are used for checking if a value equals another value. In if statements you use the two or thee equals symbol operator.
Thus to fix your problem, change the if to:
if (msg.guild.id === bcid) {
// Your code here
}
Check out this link to learn about the difference between == and ===.

Resources