Why is useState not triggering a re-render on a string - react-hooks

i have the following code:
const [error, setError] = useState('');
const errorResponse = error => {
// do something
console.log(error.message); // Network Error!
setError(error.message);
}
I call the errorResponse method in a .catch() block when an axios call fails. However, when the error message gets passed onto the errorResponse, and the setError() method subsequently, the re-render did not happen and my error message is not displayed for the user.
Not sure what I am doing wrongly here.

Related

How to fetch a message with the ID, without having it in cache

So I programmed a system that saves the ids of certain channels (plus messages) and saves them in a file. After restarting the bot, the IDs will be read and reused. For example, fetching the specific message to edit it, therefore. Unfortunately, the cache is undefined, empty or an error occurs. Could somebody show me how to fetch a message which isn't in the cache?
Example code for an existing message and channel:
const {Discord, Client, Intents, Permissions, MessageEmbed} = require('discord.js');
const bot = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MEMBERS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS, Intents.FLAGS.GUILD_MESSAGE_TYPING, Intents.FLAGS.GUILD_PRESENCES, Intents.FLAGS.DIRECT_MESSAGES, Intents.FLAGS.DIRECT_MESSAGE_REACTIONS, Intents.FLAGS.DIRECT_MESSAGE_TYPING, Intents.FLAGS.GUILD_VOICE_STATES]});
bot.channels.cache.get('597102497420673025').messages.cache.get('959413368911966251').embeds;
Error:
var test = bot.channels.cache.get('597102497420673025').messages.cache.get('959413368911966251').embeds;
^
TypeError: Cannot read properties of undefined (reading 'embeds')
at Client.<anonymous> (D:\E-verysBot\index.js:2288:99)
at Client.emit (node:events:402:35)
at WebSocketManager.triggerClientReady (D:\E-verysBot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:384:17)
at WebSocketManager.checkShardsReady (D:\E-verysBot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:367:10)
at WebSocketShard.<anonymous> (D:\E-verysBot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:189:14)
at WebSocketShard.emit (node:events:390:28)
at WebSocketShard.checkReady (D:\E-verysBot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:475:12)
at WebSocketShard.onPacket (D:\E-verysBot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:447:16)
at WebSocketShard.onMessage (D:\E-verysBot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:301:10)
at WebSocket.onMessage (D:\E-verysBot\node_modules\ws\lib\event-target.js:199:18)
Node.js v17.3.0
You fetch a message, to cache it.
// asynchronously
const channel = client.channels.cache.get(`channelId`);
const message = await channel.messages.fetch(`messageId`);
return message.embeds;
// synchronously
const channel = client.channels.cache.get(`channelId`);
channel.messages.fetch(`messageId`).then(message => {
return message.embeds;
})
I hope this fixes your problem!

Uno platform: invoke UI update from async thread

I have an async member which ultimately needs to invoke some UI updates, after getting some data from a server.
I think I need something like BeginInvokeOnMainThread, or Dispatcher.Invoke, but neither of these appear to be recognized in the Uno context.
Here's the essence of what I have:
public async Task LoadList()
{
...
// get data
Uri uri = new Uri("https://...");
response = await httpClient.GetAsync(uri);
// display
BeginInvokeOnMainThread () =>
{
... update the UI ...
});
}
But I get the error CS0103 The name 'BeginInvokeOnMainThread' does not exist in the current context UnoTest.Droid, UnoTest.UWP, UnoTest.Wasm
BeginInvokeOnMainThread / Dispatcher.Invoke / Control.Invoke were never a good idea.
Uno should have a SynchronizationContext that is automatically used by await, so manual thread marshaling should not be necessary:
public async Task LoadList()
{
...
// get data
Uri uri = new Uri("https://...");
response = await httpClient.GetAsync(uri);
// display
... update the UI ...
}

RXJS How do I load an array of images while successfully handling errors?

I am looking to preload a bunch of images, and have discounted base64 and createObjectURL so i'd take a better option, but this is what I have.
Anyway this is what I am looking at, a function which does this. Loads an array of URLS as images.
const urls = ["lol.jpg"];
const images = urls.map((url) => {
const imageElement = document.createElement('img');
const imageComplete = fromEvent(imageElement, 'load');
imageElement.src = targetURL;
return imageComplete;
});
forkJoin(images)
But how do I correctly handle loading errors here? I have added a new fromEvent but now I have 2 events where I used to just have one, and further one of them is the special error case.
const urls = ["lol.jpg"];
const images = urls.map((url) => {
const imageElement = document.createElement('img');
const imageComplete = fromEvent(imageElement, 'load');
const imageError = fromEvent(imageElement, 'error');
imageElement.src = targetURL;
return imageComplete; // <--- not good enough now
});
forkJoin(images)
Is it correct to listen for an error here? Ultimately I need to know if any of these fail and consider them all failures but during my tests, a 404 doesn't catchError anywhere and this brings me to this question.
The answer, in part, depends on what fromEvent(imageElement, 'error') does here:
fromEvent(imageElement, 'error').subscribe({
next: val => console.log("next: ", val),
error: err => console.log("error:", err)
});
If you do this, and you receive an error, does the event trigger next or error? Either way, I assume you want to remove imageElement if it fails to load.
If it triggers error, then you can do this:
const imageComplete = fromEvent(imageElement, 'load');
const imageError = fromEvent(imageElement, 'error').pipe(
catchError(err => {
imageElement.remove();
return throwError(err);
})
);
imageElement.src = targetURL;
return merge(imageComplete, imageError);
If it triggers next, then you can switch imageError into a stream that errors out by throwing an error like this:
const imageComplete = fromEvent(imageElement, 'load');
const imageError = fromEvent(imageElement, 'error').pipe(
tap(x => {
imageElement.remove();
throw(new Error(x.message));
})
);
imageElement.src = targetURL;
return merge(imageComplete, imageError);
Now, forkJoin will fail with your error if any of its sources fail. If you don't want that, you need to handle the error before it reaches your forkJoin.
Retry failed images a few times instead
The trickiest bit here is that you need to create an image element as part of your stream so that when you re-try it will not just resubscribe to an event of an already failed element.
The other tricky bit is that you want to create your imageElement as part of subscribing to your stream rather than as part of its definition. That's what defer essentially accomplishes for you.
With that out of the way, not many changes, and you can re-try loading your image pretty simply. You can read up on retryWhen if you want to make the process a bit more sophisticated (Like delay a bit before retrying).
const images = urls.map(targetURL =>
defer(() => of(document.createElement('img'))).pipe(
mergeMap(imageElement => {
const imageComplete = fromEvent(imageElement, 'load');
const imageError = fromEvent(imageElement, 'error').pipe(
catchError(err => {
imageElement.remove();
return throwError(err);
})
);
imageElement.src = targetURL;
return merge(imageComplete, imageError);
}),
retry(5),
catchError(err => {
console.log(`Failed to load img (${targetURL}) 5 times`);
// Throw error if you want forkJoin to fail, emit anything else
// if you want only this image to fail and the rest to keep going
return of(new DummyImage());
})
)
);
forkJoin(images);
In this case, since we've dealt with errors before they hit the forkJoin, we can expect the array of images to contain a DummyImage anywhere that an image failed to load 5 times. You can make DummyImage anything, really. Have a low-res default img loaded locally, for example.
If you return throwError(err) instead, then the entire forkJoin will fail the moment any image fails to load 5 times (It'll still retry 5 times though) and you'll not get any images. That might be what you want?

PublishRequest<T> IBus extension equivalent in v5.x

With v5 PublishRequest extension was removed from the IBus interface.
We used the callback to handle multiple response types that could be returned from the consumer ( Faults, Validations, actual responses, etc )
What is the equivalent way of publishing a message and wiring up multiple response types ?
// Request/Response contracts, may also return validation failure or fault contract
Request<TMessage> request = await bus.PublishRequest<TMessage>( msg, context => {
context.Handle<TResponse>( value => ... );
context.Handle<TValidation>( value => ... );
context.Handle<Fault>( value => ... );
context.CorrelationId = ...
context.Headers.Set( ... );
});
await request.Task;
You can use the new syntax, which is much cleaner overall.
var client = Bus.CreateRequestClient<RegisterMember>();
var (registered, existing) =
await client.GetResponse<MemberRegistered, ExistingMemberFound>(
new RegisterMember() {MemberId = "Johnny5"});
This will return either of the two responses, and if a fault occurs, either will throw the faulted request exception.
You can also use a request handle to add headers, etc.
var client = Bus.CreateRequestClient<RegisterMember>();
var request = client.Create(new RegisterMember()
{MemberId = "Johnny5"});
// the request is also the send pipe configurator, so...
request.UseExecute(context => context.CorrelationId = someId);
var (registered, existing) =
await request.GetResponse<MemberRegistered, ExistingMemberFound>();
You can see a working test case in the future tests:
https://github.com/MassTransit/MassTransit/blob/develop/src/MassTransit.Futures.Tests/Request_Specs.cs#L170

KendoUI datasource error event not raised on post with http 500 error

I have a datasource with error handler defined as below. In the code I am intentionally causing an error on post and the server is returning 500 plus the json data, but the error event is not being raised on post. It does fire on the read event. See http://www.ageektech.com/simplyfundraising Open your browser debugger, refresh the page, click edit change any value, click update. Need help figuring out why the error event is not triggered.
Thanks,
Dan
schema : {
model : myModel,
data : "__ENTITIES",
errors: function(e) {
debugger;
// var xhr = e.xhr;
// var statusCode = e.status;
// var errorThrown = e.errorThrown;
//alert(JSON.parse(e.responseText).error.innererror.message);
return e.errors;
}
This is not the way to subscribe to the error event of the DataSource. The schema.errors setting is used for a different purpose.
Schema.errors should contain the name of the JSON field that contains error messages.
e.g.
schema: { errors: "Errors" }
For when you are returning JSON like:
{ "Errors": "Stuff went wrong" }

Resources