Apollo Client React container add created element to paginated list of elements without refetching - reactjs

This title is quite confusing, but I will try to explain the best that I can. I have a situation where I am collecting and displaying a list of data elements from the server in React Native. It uses a query that sends a GraphQL parameter to the server to limit the initial request to the first 15 elements.
query GetElements ($count: Int) {
elements (count: $count) {
id
name
tye
}
}
As previously stated, this will query the main list with an initial count of 15 elements.
I have another page of the app that a user can create a new element on the backend using a different GraphQL query.
My question is: Is there a way to easily update the main list of elements to include the newly created element without performing any addition network requests? In other words, I want to be able to simply add the new element to the main list of elements whenever the create command is successful.
The problem is: Apollo's readQuery command on the update proxy will not return to me the appropriate data set to update unless I know the variables that were send with the initial query; this includes the pagination count variable.

You can now define the key for the queries cache store like this:
query AllItems($cursor: String, $limit: Int, $query: String) {
items(cursor: $cursor, limit: $limit, query: $query) #connection(key: "AllItemsQuery") {
count
cursor
has_next
has_prior
data{
...CoreItem
}
}
}

if you would just like to receive the added item, it seems like you want subscriptions :: http://dev.apollodata.com/react/subscriptions.html

Related

MongoDB, invoke update in MongoDB from toplevel updateMany

I want to update a read optimized MongoDB, meaning I don't have references, only copies of itself.
relevant types:
item: {
slug: string
tag: Tag[]
}
tag: {
slug: string
count: number
}
itemsByTag: {
tagName: string
item: Item[]
}
Szenario:
Add item (db.save)
Update tags count (for ... db.findOneAndUpdate({upsert: true}))
Update tagcount in all items that have the tag ( for tag ... db.updateMany())
NOW COMES THE WEIRD PART
Get all items that have been updated (db.find())
Update items in itemsByTags (for tag for item ... db.findOneAndUpdate())
Since I have to know which items to update and update them accordingly in itemsByTags (but without some fields like _id,__v and createdAt etc.). Worst case szenario, I have all the items in the database in my software and that could be huge.
An Idea was to only insert the new item that was created, and the rest, increase the counts, but I still would get all slugs(used as Id) and counts for the tags and update only partially, but still ALL items.
I was wondering if there is a way to chain the requests in MongoDB, for example whenever the updateMany finds a matching tag and updates it, it also goes to the itemsByTag for that tag and updates the count in all those items there without sending something back to the software.

ng2-smart-table display list of object

Is there a way to display a list of objects in a single table cell for ng2-smart-table? I have tried creating a renderComponent but I am getting an empty value. Another question is will the filtering and sorting still work for this?
As I understood , You have a object and you want to display that data in ng2-smart-table.
For that follow this step.
import { LocalDataSource } from 'ng2-smart-table';
source : any = LocalDataSource;
When you call API then you have to set that data in source.
this.apiService.POST({}, 'getProductList').subscribe((res) => {
console.log(res);
this.source = new LocalDataSource(res.data); // Set response as per your res.
});
As you can see I have also set one array and that array has objects of data and I have set in table.
I hope this may help you. :)

Firebase cloud function not updating record

imagine this scenario:
You have a list with lets say 100 items, a user favorites 12 items from the list.
The user now wants these 12 items displayed in a new list with the up to date data (if data changes from the original list/node)
What would be the best way to accomplish this without having to denormalize all of the data for each item?
is there a way to orderByChild().equalTo(multiple items)
(the multiple items being the favorited items)
Currently, I am successfully displaying the favorites in a new list but I am pushing all the data to the users node with the favorites, problem is when i change data, their data from favorites wont change.
note - these changes are made manually in the db and cannot be changed by the user (meta data that can potentially change)
UPDATE
I'm trying to achieve this now with cloud functions. I am trying to update the item but I can't seem to get it working.
Here is my code:
exports.itemUpdate = functions.database
.ref('/items/{itemId}')
.onUpdate((change, context) => {
const before = change.before.val(); // DataSnapshot after the change
const after = change.after.val(); // DataSnapshot after the change
console.log(after);
if (before.effects === after.effects) {
console.log('effects didnt change')
return null;
}
const ref = admin.database().ref('users')
.orderByChild('likedItems')
.equalTo(before.title);
return ref.update(after);
});
I'm not to sure what I am doing wrong here.
Cheers!
There isn't a way to do multiple items in the orderByChild, denormalising in NoSQL is fine its just about keeping it in sync like you mention. I would recommend using a Cloud Function which will help you to keep things in sync.
Another option is to use Firestore instead of the Realtime Database as it has better querying capabilities where you could store a users id in the document and using an array contains filter you could get all the users posts.
The below is the start of a Cloud function for a realtime database trigger for an update of an item.
exports.itemUpdate = functions.database.ref('/items/{itemId}')
.onUpdate((snap, context) => {
// Query your users node for matching items and update them
});

How to add items to an array one by one in groovy language

I´m developing a grails app, and I already have a domain class "ExtendedUser" wich has info about users like: "name", "bio", "birthDate". Now I´m planning to do statistics about user´s age so I have created another controller "StatisticsController" and the idea is to store all the birthDates in a local array so I can manage multiple calculations with it
class StatisticsController {
// #Secured(["ROLE_COMPANY"])
def teststat(){
def user = ExtendedUser.findAll() //A list with all of the users
def emptyList = [] //AN empty list to store all the birthdates
def k = 0
while (k<=user.size()){
emptyList.add(user[k].birthDate) //Add a new birthdate to the emptyList (The Error)
k++
}
[age: user]
}
}
When I test, it shows me this error message: Cannot get property 'birthDate' on null object
So my question is how is the best way to store all the birthdates in an single array or list, so I can make calculations with it. Thank you
I prefer to .each() in groovy as much as possible. Read about groovy looping here.
For this try something like:
user.each() {
emptylist.push(it.birthdate) //'it' is the name of the default iterator created by the .each()
}
I don't have a grails environment set up on this computer so that is right off the top of my head without being tested but give it a shot.
I would use this approach:
def birthDates = ExtendedUser.findAll().collect { it.birthDate }
The collect method transforms each element of the collection and returns the transformed collection. In this case, users are being transformed into their birth dates.
Can you try:
List dates = ExtendedUser.findAll().birthDate

How use caching to improve the performance of a classified website?

I have built classified website using Yii php framework. Now it is getting a lot of traffic. So I want to using caching to optimize the performance of the website.
There are two controllers I want to optimize.
One is the thread list controller: (example) http://www.shichengbbs.com/category/view/id/15
The other one the the thread controller: (example) http://www.shichengbbs.com/info/view/id/67900
What I have done:
the thread list is cached for 3mins.(The other option is update the thread list only when new thread comes)
set the last-modified time HTTP header for the thread view. (expire time is not set, as some user complain that the page appears unchanged after editing)
Partial caching the categories navigation fragment.(It appears on the left side of every page)
Use htaccess to set expire header for img/html/css/js.
Considered database sql caching for the thread list, but not done. As I thought it is the same as 1.
What else can I do to improve the website performance?
I assume you have done the Performance Tuning guide point 1 and 3. It's really helpful.
For number 2 you can use the CHttpCacheFilter
class CategoryController extends Controller {
private $_categoryLastUpdate;
public function filters(){
return array(
array(
'CHttpCacheFilter + view',
'cacheControl' => " max-age=604800, must-revalidate",
'etagSeedExpression' => function() {
return $this->getCategoryLastUpdate();
}
'lastModifiedExpression' => function() {
return $this->getCategoryLastUpdate();
}
)
)
}
public function actionView($id){
$object = Category::model()->findByPk($_GET['id']);
$this->render('view', array('object' => $object));
}
public function getCategoryLastUpdate(){
if (!isset($this->_categoryLastUpdate)){
$obj = Category::model()->findByPk($_GET['id'], array('select' => 'lastUpdate'));
$this->_categoryLastUpdate
}
return $this->_categoryLastUpdate;
}
}
It basically will calculate the ETag and LastUpdate by the category. And to save the query, it will first only calculate the lastUpdate of the Category object.
And for number one, you can always use the CCacheDependency. Just make a field in the thread list object, e.g. lastUpdate. And when a new thread submitted, just update the field and use it for the CCacheDependency.
Since I see you are using a very large pagination, I think you want to read about Four Ways to Optimize Paginated Displays (if you use MySQL for your database and thread search/list).
Try using a Cache Manager with Memcache or APC. For example, http://code.google.com/p/memcache-flag/ . When you edit the list, then you can invalidate the cache item or tag. I suppose it could also just be done with regular APC / Memcache functions if you design is simple (set a key and delete it when it is no longer valid).
Use this to store serialized (or automatically serialized) data instead of retrieving it from mysql.

Resources