How to play sound Whenever I recieve new notification witj reactJs? - javascript

actually I'm working on reactJs project with laravel on backend I want to play sound whenever I recieve notification I tried but I didn't get a solution.
this is my code :
useEffect(() => {
let statusInterval = setInterval(() => {
getData();
}, 10000)
return () => {
clearInterval(statusInterval);
}
}, [])
async function getData() {
let result = await fetch(`${API_ENDPOINT}/api/listComplain`);
result = await result.json();
setData(result)
}
I want also to know if there's another way better that setInterval to get data
Thanks in advance for your help.

Classic would have been to use web sockets for this instant notification notices to clients. But this requires some setup and knowledge. Actually I wrote a service that you can POST to it and it will send data (like a string) to the clients, which is what you need. https://rejax.io .

Related

axios react get real-time data display

I made an Axios get request to get data to display it with react
export function Wareh() {
const [wareh, setWareh] = useState([{}]);
useEffect(() => {
axios.get("http://localhost:1515/wareh").then((response) => {
setWareh((existingData) => {
return response.data;
});
});
}, []);
return wareh;
}
the problem here if i update my data i have to refresh the page to see the udpate Here is my question :
how to make itto be like r like if any changes happens in the database it reflects the get request.
There are 3 ways to achieve this. Either you can do it using
Long pooling
In this technique, you can set Interval and call the same endpoint to refresh the data with the passage of time.
setInterval(() => fetchWareh(), 5000)
Let's assume you can shift your Axios call to a function named: fetchWareh and call the same function after every 5 seconds
Server Sent Event
This is approach is quite similar to the first approach. You read more about from here:
https://www.w3schools.com/html/html5_serversentevents.asp
Implement socket on server & client
A most recommended to do it through socket.io to fetch real-time data.
Socket Documentation Here

Issues connecting data stream to users responses in Google Voice App

I am currently developing a voice agent to be used in a smart speaker where users will ask about some items that are being stored in a data stream. The ultimate goal is that users ask about items' names in the stream and google actions through voice will tell them the details about those items as presented in another column in the stream.
To do this, I linked a spreadsheet to Axios to stream the content of the spreadsheet as data to be read in a webhook in google actions. The link to the data stream is HERE.
Honestly, I am new to developing apps for google actions and new to javascript overall so I might be doing silly mistakes.
In the graphical interface for google actions, I am setting a type for the items I want the user to ask about.
Then, I set an intent to recognize the item as a data type and be able to send this to the webhook.
The cloud function in the webhook is as follows:
const { conversation } = require('#assistant/conversation');
const functions = require('firebase-functions');
require('firebase-functions/lib/logger/compat'); // console.log compact
const axios = require('axios');
const app = conversation({debug: true});
app.handle('getItem', async conv => {
const data = await getItem();
const itemParam = app.types.Item;
// conv.add("This test to see if we are accessing the webhook for ${itemParam}");
data.map(item => {
if (item.Name === itemParam)
agent.add('These are the datails for ${itemParam}. It is located in zone
${item.Zone}, at level ${item.Level}');
});
});
async function getItem() {
const res = await axios.get('https://sheetdb.io/api/v1/n3ol4hwmfsmqd');
console.log(res.data);
return res.data; // To use in your Action's response
}
exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
What the webhook is doing is getting the stream with the getItem function and then mapping the data to find the Name in the stream to match the item parameter (ItemParam) as identified by the user.
However, one of the main problems I have is that when trying to access the item from the user, I am using app.types.Item, but this does not work as when testing I get an error saying: "error": "Cannot read property 'Item' of undefined". I think what is happening is that I am not using the correct way to call the Item in the conversation app.
Also, I am not sure exactly how the linking to the database will work. In other works, I am not sure if
data.map(item => {
if (item.Name === itemParam)
agent.add('These are the datails for ${itemParam}. It is located in zone
${item.Zone}, at level ${item.Level}');
will work.
I have tried multiple things to solve but I am really struggling so any help with this would be really appreciated. Also, I know that I rushed to explain things, so please let me know if you need me to explain better or clarify anything.
Thank you
There are three points I am seeing that won't work.
First, app.types.Item is not the way to get this parameter. You should instead use conv.intent.params['Item'].resolved to get the user's spoken name.
Second, you are trying to use agent.add to include text, but there is no agent in your environment. You should instead be using conv.add.
Third, the text you are sending is not properly escaped between backticks ``. It is the backtick that allows you to use template literals.
Altogether your code can be rewritten as:
const { conversation } = require('#assistant/conversation');
const functions = require('firebase-functions');
require('firebase-functions/lib/logger/compat'); // console.log compact
const axios = require('axios');
const app = conversation({debug: true});
app.handle('getItem', async conv => {
const data = await getItem();
const itemParam = conv.intent.params['Item'].resolved;
data.map(item => {
if (item.Name === itemParam)
conv.add(`These are the datails for ${itemParam}. It is located in zone
${item.Zone}, at level ${item.Level}`);
});
});
async function getItem() {
const res = await axios.get('https://sheetdb.io/api/v1/n3ol4hwmfsmqd');
console.log(res.data);
return res.data; // To use in your Action's response
}
exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);

Async API call inside an infinite while loop using Axios in NODE JS

Let me begin by saying that I am a beginner to Asynchronous JavaScript and it took me quite a while to wrap my head around the concept.
Now, coming to the situation at hand. I wanted to write a code that would automatically detect text from a folder containing multiple screenshots using an OCR API, whose documentation can be found here : https://ocr.space/OCRAPI
The OCR uses two engines which can produce different results. The code should run with the default engine specified and display the contents. If the result is satisfactory, the user can chose to move on with the next screenshot, or make another api request with a different engine.
I tried to use an infinite while loop to achieve this:
const fs = require("fs")
const imageToBase64 = require("image-to-base64")
const apikey = "helloworld"
let engine = 1
fs.promises
.readdir("./screenshots")
.then((files) => {
for (const file of files) {
while (true) {
console.log("Making an API Request")
imageToBase64("./screenshots/" + file)
.then((res) => {
const form = new FormData()
form.append("base64Image", "data:image/jpeg;base64," + res)
form.append("OCREngine", engine)
axios
.post("https://api.ocr.space/parse/image", form, {
headers: { apikey, ...form.getHeaders() },
})
.then((response) => {
console.log(response.data.ParsedResults[0].ParsedText)
/*Code to ask the user whether the result is satisfactory or not.
if yes, break out of the while loop, otherwise change the engine and make the request again*/
engine = 2
})
.catch((error) => console.log(error))
})
.catch((error) => console.log(error))
}
}
})
.catch((error) => console.log(error))
The infinite while loop appears to continue the execution and not wait for the user input.
Can anyone help me out with the correct method of implementing this idea?

How to delay DB query and ignore requests that happen in between with JS?

I am using Quill as a rich text editor for my Node / Express web app.
Quill API has a method called "on" (https://quilljs.com/docs/api/#on) to fire an event every time the editor selection or text changes.
I am using this method to save the contents of the editor to a MySQL database, using quill.root.innerHTM to capture the entirety of the content in HTML format.
This works well, but my problem is that this approach fires a POST request to my Express endpoint for every keystroke of the user. I don't want to overwhelm the server and I don't need to save every keystroke variation.
One solution I imagined was to delay the DB query by 3 seconds and fire only one request with the most recent content of the editor.
I tried using setTimeout() to achieve this like so:
app.post('/editor', (req, res) => {
let post = true;
const id = req.query.id;
const data = req.body.content;
setTimeout(() => {
if (post == true) {
post = false;
db.connection.query('UPDATE my_table SET content = ? WHERE id = ?', [data, id], (error) => {
if (error) {
res.status(500).send("Internal server error")
}
res.status(200).send();
});
}
console.log('data posted');
}, 3000);
});
As you can see, I tried using a boolean. I know why this code doesn't work, but I couldn't figure out a way to "ignore" the requests that happen between the time intervals, and only fire a DB query with the latest data from the editor.
Thanks!
I managed to solve the problem using "debounce" from Underscore.js (http://underscorejs.org/#debounce). It works really well!
I did not touch the server route. I implemented it on the frontend. Here's what the code looks like now:
const quill = new Quill('#editor', options);
function update() {
let quillHtml = quill.root.innerHTML;
let quillContent = {
"contents": `${quillHtml}`
};
postData('/editor', id, quillContent);
}
const lazyUpdate = debounce(update, 1000);
quill.on('text-change', lazyUpdate);
postData() is just a helper function to generate a POST request using fetch()

The click action in mailinator page does not work with protractor

I'm trying to automate the verification code sent to an email in mailinator, when I run the test therror is: "TimeoutError: Wait timed out after 35001ms", I'm thinking that is a problem with the async functions but I'm not secure about that.
const emailRow = element(by.className("tr.even.pointer.ng-scope"));
this.setCode = async function() {
let windows = await browser.getAllWindowHandles();
await browser.switchTo().window(windows[1]);
await browser.wait(ExpectedConditions.visibilityOf(emailRow), 50000);
browser.actions().mouseMove(emailRow).click().perform();
await browser.wait(ExpectedConditions.visibilityOf(emailCode), 35000);
}
I also tried this
this.setCode = async function() {
let windows = await browser.getAllWindowHandles();
await browser.switchTo().window(windows[1]);
await browser.wait(ExpectedConditions.elementToBeClickable(emailRow), 50000);
emailRow.click();
await browser.wait(ExpectedConditions.visibilityOf(emailCode), 35000);
}
But I have the same problem, in the screen I can't see that the test perform the click, I put an sleep after the click in the emailRow but doesn't work, in the image there is the page that i want to perform the click.
I think your best bet is to use their api, instead of going to their website and read the email there. In protractor, this is very easy. depending on whether or not you have a premium account with them you can use a public or a private team inbox. In the case of a public inbox, perform something similar to the following:
const checkMailinatorPublicEmail = async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
let requestUrl = 'https://mailinator.com/api/v2/domains/public/inboxes/your_inbox_name_here';
let responseBody = await fetch(requestUrl);
let responseJson = await responseBody.json();
return responseJson;
}
Now, you have all the email in the inbox in your response body as a json object. To keep this simple, do not use a static public team inbox, instead use a random inbox name so that each time you will only have one email in the inbox and you can parse that email to your needs.
I believe you should try the second approach. In the first approach, you are waiting for an element to be visible that does not guarantee an element is clickable.
By looking at second approach, the code looks fine. My suggestion is to try changing click method like below
browser.executeScript('arguments[0].click()', emailRow.getWebElement());
Hope this will help
Happy coding!

Categories