So basically I have a chat app in html and nodejs and js and I am trying to load messages that were sent previously so people can see chat history if they join but when they join it works but if say I reload the page on my computer while they are on the site it would send duplicate value when I want it to only show once.
let msgArray = []
const updateCounter2 = ctx => {
ctx.io.emit('count', Object.keys(ctx.io.sockets.sockets).length);
for (var i in msgArray) {
ctx.io.emit('message', msgArray[i]);
}
};
server([get('/', ctx => render('msg.hbs')),
socket('connect', updateCounter2),
socket('message', ctx => {
console.log(ctx.data);
ctx.io.emit('message', ctx.data);
msgArray.push(ctx.data)
})
]);
is part of my code but this is the code to get messages and push them to an array to display when a user loads the page.
Like if I reload the page it works fine but if I reload once someone is on it they get sent the data once again which is not supposed to happen.
Like I am probably repeating myself but I open the page on my phone and on my computer and when I have it open on computer and phone and reload on phone it sends duplicates to computer. (but then if I reload it removes the duplicates and only sends the non dupes)
Sending clientside message worked
ctx.socket.emit('message', msgArray[i]);
Related
I'm currently writing using Google-Apps-Scripts to do change labels on threads and messages. When the script completes, the payloads are moved, but the display on the user frontend does not change until the user interacts with Gmail.
Is there a way to push a refresh command to Gmail? How can I gracefully display "job's done" to the user so they know that messages are now appropriately labeled?
I am working directly against the Gmail API, not GmailApp. I discovered ActionResponseBuilder.setStateChanged(), but the problem is I am currently not working with any sort of frontend interface. This is all in the background.
Here is an abbreviated example of some of the code I'm using to grab messages to modify (as requested):
function changeLabel(ids,oldLabel,newLabel) {
Gmail.Users.Messages.batchModify({
"ids":ids,
"addLabelIds":oldLabel,
"removeLabelIds":newLabel
},"me");
}
function start() {
// Labels to work with
const FOO = "Label_5095729546757874255";
const BAR = "Label_5102306845672214551";
// API call to retrieve list of messages by Label
var msgIdsByLabel = new MessageIndex(FOO);
// API call to retrieve message contents
var payloadMessages = new Messages(msgIdsByLabel);
var manifestMessagesToMove = [];
for (var i=0;i < Object.keys(payloadMessages.response).length; i++) {
// Criteria for selecting messages to move goes here
manifestMessagesToMove[i] = payloadMessages.response[i].id;
}
// Change labels of Message Ids
changeLabel(manifestMessagesToMove,FOO,BAR);
// ??? Refresh Gmail Interface ???
}
Unfortunately this isn't possible.
The Gmail UI can't be refreshed from Apps Script as it is run in the cloud as a separate session to that which is being viewed in the web browser by a user. The two aren't connected - and the same goes for the Gmail API.
If you don't have a front-end interface (aka a Gmail Add-on utilising CardService) then there is not a way of displaying a message to the user, either. The refresh will have to be done manually.
I have a page where it has 2 different endpoint calls to 2 different routes around the same time. The second one returns successfully, however, the first one stays in pending status.
I have checked the server logs and the request is received by the server and a response is sent back.
For some reason, the status code of the pending one is 200 even though it says pending.
I tried to replicate this problem in multiple machines but failed. However, in the users' machine, it can be replicated every single time.
The user does not have any browser extensions. (Tried on incognito and problem still occurs)
All calls are in https
The page which does the requests generally has ~100% CPU for a few seconds.
After waiting for a while the user gets the Page unresponsive tab.
Users Chrome version: 81.0.4044.26 / macOS Mojave. I also tested with the same versions and couldn't replicate.
I'm using axios and the following code to fetch data.
const fetchData = async () => {
try {
const result = await axios(url);
..
} catch (error) {
..
}
};
I couldn't figure out why this was happening and how to fix it. Would appriciate help.
Thanks
Related Topic: What does "pending" mean for request in Chrome Developer Window?
Im using React, Apollo and Graphcool. I have an account page where I need to query the logged in users details:
const loggedInUser = gql`
query {
loggedInUser {
id
}
}
`;
Logging in is done on a separate page. If the user then navigates or is automatically redirected (both with React Router) to the account page then the query comes back as null. If I give the page a hard refresh then the logged in users ID comes back from the query successfully.
Im not sure why this is happening. I don't think it could be a race condition as you can navigate to the account page after 10 seconds and it still wont return the user id unless you refresh.
Do I need to user resetStore? This could be expensive for me as a lot of data which wont have changed will need to be fetched again.
I needed to refetch the query after the user logged in as Apollo had cached the previous result of null. I added this to the login function and it now works.
// I added this:
await this.props.loggedInUser.refetch();
// redirect user
this.setState({
redirect: true,
});
I have a nodeJS server, that takes JSON from three websites and sends it to be displayed on my website(in JSON). The JSON on the websites that I'm taking from is constantly updated, every 10 seconds. How can I make my NodeJS server constantly update so it has the most up to date data?
I'm assuming this isn't possible without refreshing the page, but it would be optimal if the page wasn't refreshed.
If this is impossible to do with NodeJS and there is a different method of accomplishing this, I would be extremely appreciative if you told me.
Code:
router.get("/", function(req, res){
var request = require('request-promise');
var data1;
var data2;
var data3;
request("website1.json").then(function(body){
data1 = JSON.parse(body);
return request("website2.json");
})
.then(function(body) {
data2 = JSON.parse(body);
return request("website3.json");
})
.then(function(body){
data3 = JSON.parse(body);
res.render("app.ejs", {data1: data1, data2: data2, data3: data3});
})
});
Here's some general guidelines:
Examine the APIs you have available from your external service. Find out if there is anything it offers that lets you make a webSocket connection or some other continuous TCP connection so you can get realtime (or close to realtime) notifications when things change. If so, have your server use that.
If there is no realtime notification API from the external server, then you are just going to have to poll it every xx seconds. To decide how often you should poll it, you need to consider: a) How often you really need new data in your web pages (for example, maybe data that is current within 5 minutes is OK), b) What the terms of service and rate limiting are for the 3rd party service (e.g. how often will they let you poll it) and c) how much your server can afford to poll it (from a server load point of view).
Once you figure out how often you're going to poll the external service, then you build yourself a recurring polling mechanism. The simplest way would be using setInterval() that is set for your polling interval time. I have a raspberry pi node.js server that uses a setInterval() to repeatedly check several temperature sensors. That mechanism works fine as long as you pick an appropriate interval time for your situation.
Then for communication of new information back to a connected web page, the best way to get near "real time" updates form the server is for the web page to make a webSocket or socket.io connection to your server. This is a continuously connected socket over which messages can be sent either way. So, using this mechanism, the client makes a socket.io connection to your server. The server receives that connection and the connection stays open for the lifetime of that web page. Then, anytime your server has new data that needs to be sent to that web page, it can just send a message over that socket.io connection. The web page will receive that message and can then update the contents of the web page accordingly based on the data in the message. No page refresh is needed.
Here's an outline of the server code:
// start up socket.io listener using your existing web server
var io = require('socket.io')(app);
// recurring interval to poll several external web sites.
setInterval(function () {
var results = {};
request("website1.json").then(function (body) {
results.data1 = JSON.parse(body);
return request("website2.json");
}).then(function (body) {
results.data2 = JSON.parse(body);
return request("website3.json");
}).then(function (body) {
results.data3 = JSON.parse(body);
// decide if anything has actually changed on external service data
// and whether anything needs to be sent to connected clients
io.emit("newData", results);
}).catch(function(err) {
// decide what to do if external service causes an error
});
}, 10000);
The client code would then be generally like this:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on("newData", function(data) {
// process new data here and update the web page
});
</script>
I need some help to post username and password to a web page and then invoke the click event for the log in.
In order to better understand what I'm trying to do, a good example could be the following one:
programmatically send to a bank account's web page username and password (in the relevant inputs) and then, once logged in, retrieve the balance.
This means that in my app I'll have a XAML page with 2 textboxes, 1 button and 1 textblock.
Parse a site is quite easy, so that I'd be able to get the balance but I can't send the data to the server for the log in.
I've already read several examples with WP8 but none of them allows me to understand how to proceed with WP8.1 where, apparently, things are little bit different.
I've tried with this code where I assumed the inputs are called "user" and "password":
private async void LogIn_Click(object sender, RoutedEventArgs e)
{
string url = "http://www.something.com";
WebRequest request = WebRequest.Create(url);
string postData = "user=" + textBoxUser.Text + "&password=" + textBoxPassword.Text;
byte[] send = Encoding.UTF8.GetBytes(postData);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
Stream sout = await request.GetRequestStreamAsync();
sout.Write(send, 0, send.Length);
sout.Dispose();
var myHttpClient = new System.Net.Http.HttpClient();
var response = await myHttpClient.GetAsync(url);
var dataBack = await response.Content.ReadAsStringAsync();
//Debug:
Debug.WriteLine(dataBack);
}
Even though I don't receive any error, the inputs in the response are empty and moreover I don't know how to invoke the click event of the button in the web page to submit the data.
In addition, I don't want to open the web page since everything would be managed by the 4 controls of the app.
Is there anybody who can give some suggestion or address me where I can find something which suits my need?
Thanks
Looks like you're already on the right path: putting together the correct POST request the way a browser would send it after the user submits the form.
You may however need to set Referer parameters and maybe a CSRF token or such in addition to naming the parameters correctly. The best approach would be to submit the form in an actual browser and look at the request that it sends via the built-in developer tools, then reverse-engineer that one from within your app.