How do I access a query string parameter in loopback model? - loopbackjs

My api endpoint is like as follows for a model definition product.js
api/products/9720?id_shop=1&id_lang=1
I need to access the id_shop in product.js to apply a where clause before it fetches the records from products table.
Product.observe('access', function (ctx, next) {
next();
});
How would I access id_shop and id_lang?

You can use a remote method to create a custom endpoint:
https://docs.strongloop.com/display/public/LB/Remote+methods
If you really want to alter the default behavior of Model.find(), you can use loopback.getCurrentContext() and then inject the filter for every GET request:
Product.on('dataSourceAttached', function(obj){
var find = Product.find;
Product.find = function(filter, cb) {
var id_shop = loopback.getCurrentContext().active.http.req.query.id_shop;
filter = {where:{id_shop: id_shop}};
return find.apply(this, arguments);
};
});
This would overwrite any filter passed in, so you would need to handle that with additional logic.

Related

What I should use instead of resolvers?

As u already know the Local resolvers are deprecated so we can't use it as a perspective way to handling REST cache. What we should use instead of resolvers?
'field policies' are not good for that at all. Let's imagine... You have two different client queries: getBooks and getBook. Each query getting data from the rest API. Somehow we need to handle the situation when we already got the data from getBooks and runing another query getBook. getBook should not make a request because the data were already cached. We did that in resolvers before it was deprecated. We were just checking the cache and return the data if it already exists in the cache if not did a request. How we can handle this in current circumstances?
Sorry but it's a bit not what I meant. Here is a code example:
export const getBooks = gql`
query getBooks () {
getBooks ()
#rest(
type: "Book"
path: "books"
endpoint: "v1"
) {
id
title
author
}
}
`
export const getBook = gql`
query getBook ($id: Int!) {
getBook (id: $id)
#rest(
type: "Book"
path: "book/{args.id}"
endpoint: "v1"
) {
id
title
author
}
}
`
So we have two different queries. The goal is when we run both in turn the getBook should not make a REST request because we already have the same data in the cache since we get it from getBooks. Before resolvers were deprecated we handle it in resolvers. Like: if this ID is not exist in the cache just make a request if exist give me data from the cache. How we can do that now?
As u can see fetchPolicy it's completely different.
Local fields it's also not good because it's something about fields not about the whole entity.

How can I use Apollo/GraphQL to incrementally/progressively query a datasource?

I have a query like this in my React/Apollo application:
const APPLICATIONS_QUERY = gql`
{
applications {
id
applicationType {
name
}
customer {
id
isActive
name
shortName
displayTimezone
}
deployments {
id
created
user {
id
username
}
}
baseUrl
customerIdentifier
hostInformation
kibanaUrl
sentryIssues
sentryShortName
serviceClass
updown
updownToken
}
}
`;
The majority of the items in the query are in a database and so the query is quick. But a couple of the items, like sentryIssues and updown rely on external API calls, so they make the duration of the query very long.
I'd like to split the query into the database portion and the external API portion so I can show the applications table immediately and add loading spinners for the two columns that hit an external API... But I can't find a good example of incremental/progressive querying or merging the results of two queries with Apollo.
This is a good example of where the #defer directive would be helpful. You can indicate which fields you want to defer for a given query like this:
const APPLICATIONS_QUERY = gql`
{
applications {
id
applicationType {
name
}
customer #defer {
id
isActive
name
shortName
displayTimezone
}
}
}
`
In this case, the client will make one request but receive 2 responses -- the initial response with all the requested fields sans customer and a second "patch" response with just the customer field that's fired once that resolver is finished. The client does the heavy lifting and pieces these two responses together for you -- there's no additional code necessary.
Please be aware that only nullable fields can be deferred, since the initial value sent with the first response will always be null. As a bonus, react-apollo exposes a loadingState property that you can use to check the loading state for your deferred fields:
<Query query={APPLICATIONS_QUERY}>
{({ loading, error, data, loadingState }) => {
const customerComponent = loadingState.applications.customer
? <CustomerInfo customer={data.applications.customer} />
: <LoadingIndicator />
// ...
}}
</Query>
The only downside is this is an experimental feature, so at the moment you have to install the alpha preview version of both apollo-server and the client libraries to use it.
See the docs for full details.

Accessing route params within an adapter with ember

I'm having issues accessing the current route params within an adapter. I've tried looking in the store and type objects that are passed in but have not been able to find anything.
I know I could use window.href.location to access the string of the url and do some manipulation to access the route param, however I'm not comfortable hardcoding that in because the url may change.
I would recommend you to use query argument passed to a method you use to query your data.
Look at the default implementation of rest-adapter's queryRecord():
query(store, type, query) {
var url = this.buildURL(type.modelName, null, null, 'query', query);
if (this.sortQueryParams) {
query = this.sortQueryParams(query);
}
return this.ajax(url, 'GET', { data: query });
},
It has access to the query argument and uses buildURL, you can override function buildURL() or query() and adjust it the way you need.
What you need to do afterwards is to use your route or controller to read query parameters from the url and pass to the store your query object to reflect your need.
Here is the link to Ember-Data DS.Adapter API

How to get Display name of user profile manager property

When I was writing custom display template for SharePoint people search, I wanted to display the manager of the searched user. When I display the manager value returned from SharePoint people search, it displays as follows:
i:0#.f|membership|lpalmer#xyz.com
I want to show the display instead of the account name in my SharePoint display template. Let me know if this can be done either using JavaScript or just by doing some configurations on SharePoint user profile property change.
This cannot be done using just configurations. You will need to query the User Profile Service and get the Display Name using the login name the search service returns.
For obtaining any property you can use something like this:
function getProfilePropertyValueFromLoginName(loginName, propertyName, success, error) {
// Get the current client context and PeopleManager instance.
var clientContext = new SP.ClientContext.get_current();
var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);
// Get user properties for the target user.
// To get the PersonProperties object for the current user, use the
// getMyProperties method.
var personProperties = peopleManager.getPropertiesFor(loginName);
// Load the PersonProperties object and send the request.
clientContext.load(personProperties);
clientContext.executeQueryAsync(
function () {
if (success) {
success(loginName, personProperties.get_userProfileProperties()[propertyName]);
}
}, function (sender, args) {
if (error) {
error(sender, args);
}
});
}
-Hope it helps

Is there anyway to request a specific value in Facebook's Graph API not using FQL?

e.g.
FB.api('/me/permissions="user_photos"', function (response) { });
instead of
FB.api({ method: 'fql.query', query: 'SELECT user_photos FROM permissions WHERE uid=me()' }, function(resp) {
for(var key in resp[0]) {
if(resp[0][key] === "1")
console.log(key+' is granted')
else
console.log(key+' is not granted')
}
});
Yes, Theres a way called selection in graph api or more advance field expansion:
You can choose the fields (or connections) you want returned with the "fields" query parameter, Example:
FB.api('/me/permissions?fields=user_photos', function (response) { });
Graph API Explorer Demo
EDIT:
Quoted directly from graph api doc:
Selection
By default, most object properties are returned when you make a query.
You can choose the fields (or connections) you want returned with the
"fields" query parameter. For example, this URL will only return the
id, name, and picture of Ben:
https://graph.facebook.com/bgolub?fields=id,name,picture
You can also request multiple objects in a single query using the
"ids" query parameter. For example, the URL
https://graph.facebook.com?ids=arjun,vernal returns both profiles in
the same response.
The "ids" query parameter also accepts URLs. This is useful for
finding IDs of URLs in the Open Graph. For example:
https://graph.facebook.com/?ids=http://www.imdb.com/title/tt0117500/
Additionally, there is a special identifier me which refers to the
current user. So the URL https://graph.facebook.com/me returns the
active user's profile.
When retrieving Posts via the /home, /feed, or /posts connection, you
can restrict the results to only those with a location attached by
adding with=location to the URL parameters:
https://graph.facebook.com/me/home?with=location
Source: Graph API Docs