VueJS Apollo graphql store/cache data collision between queries - vue.js

I have the following data flow scenario:
UI has 3 sections: Enrolled Services, Enrolling Services, and
Search Services
User will search for existing services (upon the User
entering searchServiceText, searchResultServices gets called)
The user selects a service from the search result and enrolls in a
service. If the User's enrollment not complete (ex: no payment, not
accepted, etc), UI will show the data in the Enrolling section.
Otherwise, it will be in the Enrolled section
I have the following queries:
enrolledServices: {
query: gql(listServices),
variables() {
let idFilter = this.idFilter(this.userData.enrolledServiceIds);
return {
filter: {
or: idFilter
}
};
},
update: data => {
return _.compact(data.listServices.items);
}
},
enrollingServices: {
query: gql(listServices),
variables() {
let idFilter = this.idFilter(this.userData.enrollingServiceIds);
return {
filter: {
or: idFilter
}
};
},
update: data => {
return _.compact(data.listServices.items);
}
},
searchResultServices: {
query: gql(listServices),
variables() {
console.log('before search - enrolledServices:', this.enrolledServices); //Data Collision!!
console.log('before search - enrollingServices:', this.enrollingServices);
return {
filter: {
or: [
{ name: { contains: this.searchServiceText } }
],
and: [
{ status: { eq: 'Active' } }
]
}
};
},
skip() {
return !this.searchServiceText;
},
update(data) {
return _.compact(data.listServices.items);
}
}
enrolledServices: and enrollingServices: gets called on page load, hence UI will have 2 sections for enrolled services and enrolling services.
searchResultServices: will not be called on page load because of skip() condition. It is gets called reactively when user enters value to searchServiceText field in the UI
Getting to my issue now:
On page load as expected Service_enrolled, Service_enrolling is shown in Enrolled, Enrolling sections respectively (see below).
Enrolled Section:
Service_enrolled
Enrolling Section:
Service_enrolling
If the user sets search word in searchServiceText and clicks search, Enrolled section shows Service_enrolling (see below). User is just searching at time and he/she has not acted on the search results as yet
Enrolled Section:
Service_enrolling (enrolled service replaced with enrolling
service)
Enrolling Section:
Service_enrolling
The expected behavior in step2: I should see step 1 behavior (Service_enrolled should be in Enrolled section, Service_enrolling should be in Enrolling section) because the user has not acted on search results as yet.
Not sure why in step 2 above, there is a data collision. I have console.log to print enrolled and enrolling list in the memory/cache before hitting the search query. It shows data collision right there before hitting the search query. so search query is not contributing to the issue and there are no traces of enrolledServices, enrollingServices query execution in step 2 above. I am not sure how enrolled and enrolling data gets messed up.
Note: both enrolledServices, enrollingServices has same search query except 'idFilter' data will be different as they have different service Ids. That means, as per my understanding cache key is unique for these two queries, right?
I am absolutely sure something is missing in my approach or code but not able to figure out. Any help is much appreciated and you will save a lot of time plus for others who may have a similar issue.

Related

elastic/search-ui - facets - filter by id but display by label

Given I have some documents in my elasticsearch index with a tag field.
{
...
tag:[
{
"id":"1",
"label":{
"en":"German",
"ger":"Deutsch"
},
{
"id":"2",
"label":{
"en":"cat",
"de":"Katze"
}
}
]
...
}
I´d like to build a frontend with elastic/search-ui and provide a facet for the tag field
so that the actual filtering is applied on basis of the id subfield.
Within the framework this can be achieved by providing a simple configuration within the configuration object.
let searchConfig: SearchDriverOptions = {
...
searchQuery:{
...
facets:{
"tag.id":{type:"value",size:"5"}
}
}
}
While this works like expected it is only half of the solution.
What I want to achieve in a next step is to display the content of tag.label.en within the ui instead of the values of tag.id.
In the end the filtering should be done on basis of tag.id but in the UI the corresponding value of tag.label.en should be shown.
Is there a simple way to achieve this in elastic/search-ui?

Update data when value changes Vue Js

I have quite a complicated situation and i'm not amazing at Vue so I need some help.
I have a Firebase DB that gets an array (clients) and displays it.
const clientsRef = db.ref('clients')
firebase: {
clients: {
source: clientsRef,
//data has been retrieved from firebase
readyCallback: function() {
this.getSiteCount() // Get number of sites associated with client
this.loaded = true // Hide loader bar once this becomes true
}
}
},
On load complete getSiteCount() will get the clients unique ID and compare it against the sites DB and count how many exist. Below code simply loops around each client and then checks how many sites have the client_id of aClient['.key']. Not really important this works and gets the count and adds it to the clients array.
getSiteCount: function() {
this.clients.forEach((server, clientIndex) => {
this.clients[clientIndex].siteCount= 0
serverContactsRef.orderByChild('client_id').equalTo(server['.key']).on('child_added', (clientDetails) => {
this.clients[clientIndex].siteCount= this.clients[clientIndex].siteCount+ 1
})
})
},
Now in my html I have v-for="clients in filterClients" and the computed function...
filterClients: function() {
function compare(a, b) {
if (a.siteCount < b.siteCount) {
return 1
}
if (a.siteCount > b.siteCount) {
return -1
}
return 0
}
return this.clients.sort(compare)
}
I suspect because the getSiteCount() function runs once the clients have been pulled (0.5s delay) from the DB it's initial siteCount value is 0 and filterClients runs before those values get set. I need to delay filterClients() until the getSiteCount() function runs or need it to update automatically when the getSiteCount() function runs.
Can someone help me make sure the initial load of the page displays the clients in order of how many sites it has (siteCount)
It was in fact a Caveat.
Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
I changed
this.clients[clientIndex].siteCount= 0
to
Vue.set(this.clients[clientIndex], 'contractsNr', 0)
Updates when the data comes in perfectly now.
Thanks Jacob

lucene query filter not working

I am using this filter hook in my Auth0 Delegated Administration Extension.
function(ctx, callback) {
// Get the company from the current user's metadata.
var company = ctx.request.user.app_metadata && ctx.request.user.app_metadata.company;
if (!company || !company.length) {
return callback(new Error('The current user is not part of any company.'));
}
// The GREEN company can see all users.
if (company === 'GREEN') {
return callback();
}
// Return the lucene query.
return callback(null, 'app_metadata.company:"' + company + '"');
}
When user logged in whose company is GREEN can see all users. But when user logged in whose company is RED can't see any users whose company is RED.
I need to make this when user logged in, user should only be able to access users within his company. (except users from GREEN company).
But above code is not giving expected result. What could be the issue?
This might be related to a little warning note on the User Search documentation page
Basically they don't let you search for properties in the app_metadata field anymore. Unfortunately, this change was breaking and unannounced.
We had to make changes to our API so that we keep a copy of the app_metadatas in a separate database and convert lucene syntax to MongoDB queries, so that we can query by a chain of user_id:"<>" OR user_id:"<>" OR ....
One caveat though, you can't pass a query that's longer than 72 user_ids long. This number is so far undocumented and obtained empirically.
Also, you can't rely on Auth0's hooks to add new users to your database, as these don't fire for social logins, only for Username-Password-Authentication connections.
I hope this gave you some explanation as for why it wasn't working as well as a possible solution.
If I were you, I would look for an alternative for Auth0, which is what we are currently doing.
I finally ended up with this solution.
Used search functionality to filter users. I had to change below two files.
fetchUsers function in client\actions\user.js
changed
export function fetchUsers(search = '', reset = false, page = 0)
to
export function fetchUsers(search = '#red.com', reset = false,
page = 0)
AND
onReset function in client\containers\Users\Users.jsx
changed
onReset = () => { this.props.fetchUsers('', true); }
to
onReset = () => { this.props.fetchUsers('#red.com', true); }

Not getting results field after querying task by ID in Lookback API

I'm trying to query tasks by ObjectID to get their most recent snapshots. I'm trying the API out, and am not getting the expected results that I was hoping for after reading the docs. I don't get a results field in the response object. Here's my code:
_loadTaskSnapshot: function() {
let snapshot = Ext.create('Rally.data.lookback.SnapshotStore', {
context: {
workspace: '/workspace/2290039850'
},
"find": {
"ObjectID": 34858774310,
"_ValidFrom": {
"$gte": "2016",
"$lt": "2017"
}
},
"fields": ["Name", "Estimate", "ToDo", "TimeSpent"],
});
return snapshot.load();
}
This is the store with 18 snapshots for the specified task. The first snapshot is opened. You can see there is no results field where I could find the Name, Estimate, ToDo, and TimeSpent:
Alejandro, you are asking for the changes in the fields, not the values of the fields. This is a common misconception with the lookback api. There is a special way to get the current values shown in the help pages available inside Agile Central.
Any information returned is actually held within the object underneath 'raw' and 'data'. Each of those may not contain any values if there has been no 'changes' to those fields at the time the snapshot was taken.

Retrieve the traffic variable in RankedReport of Adobe Sitecatalyst

Is it possible to fetch a traffic variable sProp1 along with PageName and Url when issuing a GetReport request of a Ranked report?
Let us say I have the following passed to SiteCatalyst (Omniture) via Java Script.
s.pageName = o_title; // Page Name
s.channel = o_structure; // SiteSection
s.prop1 = o_inode // Traffic variable also the Primary Key Id of the PageName
Now, if I run a RankedReport, I will get the following
PageName
PageViews
Url
Along with this info, I will also be interested in fetching the s.prop1 value. I will need the s.prop1 value to use it on my db to query the first sentence of the article from db (and other metadata) and show the results on the results page that shows the most popular pages. Can this be achieved? I mean is it possible to get the traffic variable associated with the pageName?
Thanks,
Rag
OK. I think I if I add another element (prop1) I get the breakdown. {
"reportDescription":{
"reportSuiteID":"*",
"dateFrom":"2013-03-06",
"dateTo":"2013-03-15",
"metrics":[
{
"id":"pageviews",
"name":"Page Views",
"type":"number"
}
],
"sortBy":"pageviews",
"elements":[
{
"id":"siteSection"
},
{
"id":"page"
},
{
"id":"prop1"
}
],
"locale":"en_US"
},
"validate":"false"
}