how to access subscribeToMore when using ApolloClient.query() manually onClick - react-native

I have a scenario when where I am calling a gql query manually using ApolloClient.query(), but the prob is this way I dont get subscribeToMode in result data ... running the query automatically on component mount works fine...
any idea about how to use subscribeToMode in on manual query?
this is what Iam trying to achieve...
this.props.client.query({ query:getPost, variables:{id:100} })
.then(data => {
this.subscription = data.data.subscribeToMore({
// subscription code here...
})
})
.catch(error => {
console.log(error);
});
let me explain the scenario..
1) I have a request form filed and submitted, records goes to the db, I got _id back... and now waiting for the approval of request on the same screen..
2) now someone else on other screen got the new entry and just pressed the approved button, rec updated in DB..
3) now I want the approval to be shows on the screen... this should all happen instantly.. or request will expire in lets say 1 min...
now my prob is 3, how can I get the approval update on the same screen... dont want to use another component.. the recordAdd is called through ApolloClient.query()
what I need to do it after the AddRec is executed successfully and received _id, i need to set a subscription on it... but it dosnt work unless I run in under ComponentWillReceiveProps()

Related

Cycle through test data from within a Testcafe test? How to?

I'm wanting to log into an app, run several searches from test data, then log out. I don't want to login and out for each item in the data set, which would be the case if I coded this way...
dataSet.forEach(data =>{
test('Search Test', async t => {......
I would like to be able to...
test('Search Test', async t => {......
foreeach(data in Data set)
call a function to search
call a function to verify search return.
Something like this...
test('Simple Search Test', async t => {
//await t
await loginPage.login(loginName, password);
await t
.expect(getURL()).contains('home')
// Check logged in user display...
.expect(pageHeader.userName.withText(data.loggedInUser).visible).ok()
dataSet.forEach(data =>{
leftSidebar.searchWithCriteria(data.criteria, 'Filename');
recordNav.verifyTotal(data.srchresult);
});
// Log out
await pageHeader.logout();
await t
.expect(loginPage.copyRight.visible).ok();
});
enter code here
I've tried everything, but can't get it to work. Is this possible or does the entire test have to be run for each data record in the set?
TestCafe allows you to loop through test code in any manner, including iterating through custom data.
To help us determine why this does not work for you, please provide an example that I can run on my machine (including the test code, page object, and the tested page's URL).
I got it to work using this...
for (var i = 0; i < dataSet.length; i++){
leftSidebar.searchWithCriteria(dataSet[i].criteria, 'Filename');
recordNav.verifyTotal(dataSet[i].srchResult);
}

ExpressJS - Small curiosity

My thing is a small project.
In main what it does is that the "server" will get a call from the link directly what will run some functions that will update the database and the data that has to be shown.
I will show what I mean:
function updateData(){
connection.query(`SELECT * FROM muzica WHERE melodie = "${updateList()}"`, function (error, rezultat, fields) {
if (error) {console.log('err la selectare')};
//express output
let data = {
melodie: rezultat[0].melodie,
likes: rezultat[0].likes
}
console.log(data.likes);
app.get('/like', (req,res) =>{
res.json(`${data.likes}`);
});
}
setInterval(()=>{
updateData();
}, 20000)
Uhh, how to explain it, I'm so bad at this...
So, in main, I'm new to back-end work, everything that I did was based on their Documentation as I learn way faster by my needs than some guides and so on.
So, when I or someone does my http://website/like it should show just data.likes, cause that is all that I need, don't count data.melodie (i will clean that later on) after I finish all the code.
Anyway, whenever I do website/like data.likes is not updating to the new database data.likes.
For example, data.likes before were 5, in a few minutes it can be 2 but whenever I call website/like show "5" than its new value 2.
Don't be hash on me, I'm new and I want to learn as much as I can, but I can't understand the above case, by my logic it should ALWAYS show what its in database when it refreshes each 10 seconds(I run this in localhost so I will not stress any online server).
But if there is any better way to check for databases update than "setInterval" please notice me.
It's hard to learn alone without a mentor or someone else to talk about this domain.
Thank you for your time!
Kind regards,
Pulsy
You have things a bit inside out. A request handler such as app.get('/like', ...) goes at the top level and you only ever call it once. What that statement does is register an event handler for any incoming requests with the /like path. When the server receives an incoming request for /like, it will then call the function for this route handler.
You then put inside that route handler the code that you want to run to generate the response and send the response back to the client.
app.get('/like', (req, res) => {
connection.query(`SELECT * FROM muzica WHERE melodie = "${updateList()}"`, function (error, rezultat, fields) {
if (error) {
console.log(error);
res.sendStatus(500);
} else {
//express output
let data = {
melodie: rezultat[0].melodie,
likes: rezultat[0].likes
}
res.json(data);
}
});
});
The endpoints need to be outside of any functions in express.
For example, if you look at the express "hello world" example here, you will see that they have a basic app that only has a single GET endpoint defined which is "/" so you would access it by running "localhost/" or "127.0.0.1/".
In your case, you want your endpoint to be "/like", so you must define something like:
const express = require('express')
const app = express()
const port = 3000
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
app.get('/like', (req, res) => {
// do database stuff and assign data variable
// res.json(data);
}

Why does Parse LiveQuery not always trigger update/create/enter event?

I am trying to achieve a board that enables real-time editing for cooperating users. I am running a parse server using Sashido, where I have LiveQueries enabled for among other things 'Sticky'. For the frontend I have the following code:
const query = new Parse.Query(Sticky);
... some query constraints
this.subscription = await query.subscribe();
this.subscription.on('open', () => {
console.log('SUBSCRIPTION: opened');
}
this.subscription.on('create', (sticky) => {
console.log('SUBSCRIPTION: created');
}
this.subscription.on('update', (sticky) => {
console.log('SUBSCRIPTION: updated');
}
this.subscription.on('enter', (sticky) => {
console.log('SUBSCRIPTION: entered');
}
this.stickies = await query.find();
When I open my application in two different browser tabs, I get the 'SUBSCRIPTION: opened'. When I edit or create Sticky instances, I expect to get the corresponding events and see changes in the Sashido database.
However, I always see the changes in the database, but half of the times when I create or edit Sticky instances, I do not get the update/create/enter events. Note: Sometimes they do get triggered, but I have not found a sequence of events that leads to them being triggered or not, it seems to happen at random.
Can someone see what I'm doing wrong?

How to refresh v-data-table after REST API Patch call?

I have a data table in Vuetify that is populated via a REST get request, using a function "getData" that is called when the app is mounted. The <td>'s in the table have buttons that the user can hit to "lock" the period (the row/column intersection).
When they hit the button, they get a popup confirmation dialog. When they hit "OK", there is a save method called to write the current date back to the db via a REST PATCH request (see below).
My problem is, the grid is not updating with the results of the patch request. I have to manually refresh the page to see the result. What is the common pattern here? Should i pull down the data again via getData to refresh the table? Should i update the array that the data-table sits on directly?
getData method:
getData() {
var self = this;
return axios
.get("http://127.0.0.1:5000/api/estimatefinal/periods?dataset=capital")
.then(function(response) {
self.periods = response.data;
})
.catch(function(error) {
alert(error);
});
},
Save method:
save(item) {
var self = this;
axios
.patch("http://localhost:5000/api/estimatefinal/period/" + self.id, {
date: moment(self.selected_date, "YYYY-MM-DD").format(
"YYYY-MM-DDTH:m:s"
)
})
.then(function() {
this.getData(); // ????
})
.catch(function(error) {
alert(error)
});
this.getData(); // ????
this.close();
}
If your PATCH changes only one row in DB, means has visually effect on only one row on your v-data-table, then you can change the data locally when you get "success" response from back-end.
If, in other hand, your PATCH changes many other things in DB (also in v-data-table) your best option is probably to getData() after you get PATCH response.
Point is to keep that same "picture" of values in DB and on screen v-data-table.

How do I delete data in gun DB when path has multiple objects

How do I delete data when my path contains multiple objects? gun.path('saving_accounts').put(null) would delete all savings accounts.
Or, do you have a way to handle the null errors when iterating over data that has a 'deleted' object? I'm providing fully working examples to try to help in answering. Say I create gun data with this:
// localStorage.clear();
var gun = Gun();
////////////////////////////////////////////////////////////////// create record
var saving1 = gun.put({
name: "Bank of America",
accType: "Saving",
last4: "5555",
favorite: true,
status: true,
created: "some date created"
});
var saving2 = gun.put({
name: "Bank of America",
accType: "Saving",
last4: "4123",
favorite: true,
status: true,
created: "some date created"
});
var saving_accounts = gun.get('saving_accounts')
saving_accounts.set(saving1);
saving_accounts.set(saving2);
Then i can query all savings accounts with something like this:
const queryMultiple = (data_path) => {
console.log("Query for: " + data_path);
gun.get(data_path).map().val((name, ID) => {
// console.log(ID);
console.log(name.name, name.accType, ID);
});
};
queryMultiple('saving_accounts');
I tried to delete a record based on the gundb question here and wiki gun.path('object3').put(null) but I'm not sure how to change it for my application. On the savings account path, there are multiple savings accounts. So if i want to delete a specific savings account, i delete it by id but I think i'm doing it wrong. Say the id of the account i want to delete is FesxPaup8gzuNSsLFlWXMKaL:
// delete record
const deletebyID = (data_path, qID) => {
console.log("DELETE record");
gun.get(data_path).path(qID).put(null);
};
deletebyID('saving_accounts', 'FesxPaup8gzuNSsLFlWXMKaL');
But the .put(null) above will make the object FesxPaup8gzuNSsLFlWXMKaL point to null and when i list all savings accounts again with queryMultiple('saving_accounts'); I get a cannot read property name of null.
How do I delete data when my path contains multiple objects?
Side note: eventually i will nest multi transactions for a savings account under each savings account so I will have to do the same thing when deleting a account transaction that was made by mistake. Also hopefully when i delete a savings account, it automatically deletes/nulls all of that accounts transactions too but i haven't gotten past playing playing with data at this first layer.
#jtlindsey great question! You are correct though on how to delete data, even about how to delete an item inside a list/collection/table. But here is how to get the results you want:
Quick Solution:
Change your query to this:
const queryMultiple = (data_path) => {
console.log("Query for: " + data_path);
gun.get(data_path).map().val((name, ID) => {
if(!name){ return }
// console.log(ID);
console.log(name.name, name.accType, ID);
});
};
queryMultiple('saving_accounts');
And it will work. Why? Because it filters out any nulled account.
Why All the Nulls?
Deletes in GUN work like Mac OSX or Windows or Linux. The nulling tells every machine to "Put this data in the trash/recycle bin". The reason this is useful is because it lets you change your mind about deleting something, so you can recover it later if you want. (Recovering deleted content/files happens a LOT, but it something most people don't think about).
The null data also is useful for notifications! This is very applicable when you are designing frontend websites and you are rendering HTML. Let's go over a simple example:
Example
Imagine your user is checking the site on his phone, and realizes he needs to get clear up some issues that are a little bit more complicated so he logs on with his laptop. After checking the details on the laptop he decides to delete the account. Underneath his "click" action causes your run code to run:
// delete record
const deletebyID = (data_path, qID) => {
console.log("DELETE record");
gun.get(data_path).path(qID).put(null);
};
deletebyID('saving_accounts', 'FesxPaup8gzuNSsLFlWXMKaL');
Which is correct. However, if he then closes his laptop and picks his phone back up... he'll notice his account is still there!!! Which is not a good experience. But with GUN fixing this is easy because of the null notification:
gun.get(data_path).map().on((account, ID) => {
var UI = $("#account-" + ID);
if(!account){
UI.remove();
return;
}
updateUI(ID, account);
});
Now when they pick up their phone it will reflect the current state of their accounts! They'll see that it had been removed on all their devices because the null got synced to all devices.
Does that make sense? Does that your answer your question? Need help with anything else? As always, https://gitter.im/amark/gun and https://github.com/amark/gun/wiki/delete and http://gun.js.org/ .