How to add getter with string method inside an object - javascript

I have an object called headers. Inside which I want to add certain headers with some random value like:
configs = {
header : {
'x-some-id': Math.random().toString()
}
}
The config paramter is used to client which is used to send http requests. And the randomid is some id generated by a load balancer. So it will we different for every request. We dont want to create a new client for every client, hence I want to use getter function in header so that everytime a request is made, the header is automatically populated with a new id. How do I implement this using getters. ideally this is what I what to achieve:
configs = {
header : {
'x-some-id': get() { return Math.random().toString()}
}
}

The syntax for getters is
configs = {
header: {
get 'x-some-id'() { return Math.random().toString(); },
},
};

Not sure if that's what you wanted but you can use a Proxy
const configs = {
header: new Proxy({
}, {
get() {
return (Math.random() * 1000000 | 0).toString()
}
})
}
console.log(configs.header['x-some-id'])

Related

get updated query in nuxt plugin after page load

Well, I have a plugin with some functions in it, functions should update URL queries.
The problem is, everytime I execute $global.changePage(2) or $global.changeLimit(2) the console.log(query) returns an empty object and didn't return updated queries in URL.
I know NuxtJS plugins execute once we load the page but is there any way to have updated query each time I use those functions?
export default (ctx: NuxtConfig, inject: Inject) => {
const { app, query } = ctx;
const global = {
changePage (page: number) {
console.log(query);
app.router.push({
query: { ...query, page }
})
},
changeLimit(limit: number) {
console.log(query);
app.router.push({
query: { ...query, limit }
})
},
}
inject('global', global)
ctx.$global = global
}
Simply remove ctx.$global = global from the last line of your plugin.
The inject method provided by Nuxt takes care of making your global object available where it's needed, so there's really no need for you to overwrite the ctx.$global property.

why toUpperCase not working in nextjs while adding slug

I am following this link
https://nextjs.org/docs/api-reference/next.config.js/headers
adding x-slug key .I am adding like this
module.exports = {
async headers() {
return [
{
source: '/:slug',
headers: [
{
key: 'x-slug',
value: `${abc(':slug')}` // Matched parameters can be used in the value
}
]
}
];
}
};
when I using this url
https://nextjs-vetexh--3000.local.webcontainer.io/dsd
"slug" --- > dsd
but when I using toUppercase() function it is not working why
function abc(a) {
// working
// return a;
// not working
return a.toUpperCase();
}
It is giving SLUG in capital .
Expected output is "DSD"
here is my code
https://stackblitz.com/edit/nextjs-vetexh?file=next.config.js
function abc(a) {
// working
// return a;
// not working
return a.toUpperCase();
}
module.exports = {
async headers() {
return [
{
source: '/:slug',
headers: [
{
key: 'x-slug',
value: `${abc(':slug')}` // Matched parameters can be used in the value
}
]
}
];
}
};
It's probably not possible in next.config.js, but there are other options with some tradeoffs.
With getServerSideProps
You could add custom HTTP headers by matching the path for the request using getServerSideProps in _app.js:
export async function getServerSideProps(context) {
// set HTTP header
context.res.setHeader('x-slug', upperCase(context.params.slug))
return {
props: {}, // will be passed to the page component as props
}
}
The context parameter is an object containing the following keys:
params: If this page uses a dynamic route, params contains the route parameters. If the page name is [id].js , then params will look like { id: ... }.
req: The HTTP IncomingMessage object.
res: The HTTP response object.
query: An object representing the query string.
But using getServerSideProps would disable static optimization as all pages will be only server-side rendered.
More on Server-side Rendering
With Custom Server
Another way is to use a Custom Server and override the response headers.
server.get('/:slug*', (req, res) => {
res.set('x-slug', upperCase(req.params['slug']));
handle(req, res, parsedUrl);
});
A custom server will remove important performance optimizations, like serverless functions and Automatic Static Optimization.

Unable to pass parameters to service hook through find function in featherjs

Featherjs find service unable to pass extra parameters through find function. In below find service passing extra params data to service.
but unable to receive the value at service hook.
Client code :
return this.app.service('userlist').find({
query: { usersIds: { "$in" : [this.user._id]} },
paginate: false,
params:{ name:'sam' }
}).then(response => {
}).catch(error => {
console.log(error);
});
Server code (Service hook ) :
module.exports = function (options = {}) {
return async function dogetUsr (context) {
const { data } = context;
console.log('Client Param data -->',context.params.name);
return context;
};
};
params data not receiving at server -->
params:{ name:'sam' }
Output at server/service hook :
Client Param data -->undefined
For security reasons, only params.query is passed between the client and the server. In general I wouldn't recommend letting the client disable pagination unless you are guaranteed to only get a few (less than 100) records. Otherwise requests with many records can cause major issues on both sides.
If it is still something you need, you can use the disablePagination hook which lets you set the $limit to -1 if you want to disable pagination:
const { disablePagination } = require('feathers-hooks-common');
module.exports = { before: {
find: disablePagination()
} };

Feathers calling custom API method

I define my api with something like the below:
class MyFeathersApi {
feathersClient: any;
accountsAPI: any;
productsAPI: any;
constructor(app) {
var port: number = app.get('port');
this.accountsAPI = app.service('/api/accounts');
this.productsAPI = app.service('/api/products');
}
findAdminAccounts(filter: any, cb: (err:Error, accounts:Models.IAccount[]) => void) {
filter = { query: { adminProfile: { $exists: true } } }
this.accountsAPI.find(filter, cb);
}
When I want to use database adapter methods, from the client, i.e. find and/or create, I do the below:
var accountsAPIService = app.service('/api/accounts');
accountsAPIService.find( function(error, accounts) {
...
});
How I call custom methods, such as findAdminAccounts() from the client?
You can only use the normal service interface on the client. We found that support for custom methods (and all the issues it brings with it going from a clearly defined interface to arbitrary method names and parameters) is not really necessary because everything in itself can be described as a resource (service).
The benefits (like security, predictability and sending well defined real-time events) so far have heavily outweighed the slight change in thinking required when conceptualizing your application logic.
In your example you could make a wrapper service that gets the admin accounts like this:
class AdminAccounts {
find(params) {
const accountService = this.app.service('/api/accounts');
return accountService.find({ query: { adminProfile: { $exists: true } } });
}
setup(app) {
this.app = app;
}
}
app.use('/api/adminAccounts', new AdminAccounts());
Alternatively you could implement a hook that maps query parameters to larger queries like this:
app.service('/api/accounts').hooks({
before: {
find(hook) {
if(hook.params.query.admin) {
hook.params.query.adminProfile = { $exists: true };
}
}
}
});
This would now allow calling something like /api/accounts?admin.
For more information see this FAQ.

How to find a record both by id and query parameters in Ember

I'm trying to use ember-data to send a request via id and query parameters to an endpoint. The end output of the ajax call would be http://api.example.com/invoices/1?key=value. As far as I know, ember-data's store doesn't have a native way to find by both id and query parameters (neither of the following worked):
// outputs http://api.example/com/invoices/1
this.store.find('invoice', 1);
// outputs http://api.example.com/invoices?id=1&key=value
this.store.find('invoice, {id: 1, key: value});
Instead, I've been attempting to modify the invoice adapter. Our backend is Django, so we're using the ActiveModelAdapter. I want to override the method that builds the url so that if id is present in the query object, it will automatically remove it and append it to the url instead before turning the rest of the query object into url parameters.
The only problem is that I can't figure out which method to override. I've looked at the docs for ActiveModelAdapter here, and I've tried overriding the findRecord, buildUrl, urlForFind, and urlForQuery methods, but none of them are getting called for some reason (I've tried logging via console.log and Ember.debug). I know the adapter is working correctly because the namespace is working.
Here's my adapter file:
import DS from 'ember-data';
import config from '../config/environment';
export default DS.ActiveModelAdapter.extend({
namespace: 'v1',
host: config.apiUrl,
// taken straight from the build-url-mixin and modified
// very slightly to test for logging
urlForFindRecord: function(id, modelName, snapshot) {
Ember.debug('urlForFindRecord is being called');
if (this.urlForFind !== urlForFind) {
Ember.deprecate('BuildURLMixin#urlForFind has been deprecated and renamed to `urlForFindRecord`.');
return this.urlForFind(id, modelName, snapshot);
}
return this._buildURL(modelName, id);
},
// taken straight from the build-url-mixin and modified
// very slightly to test for logging
findRecord: function(store, type, id, snapshot) {
Ember.debug('findRecord is being called');
var find = RestAdapter.prototype.find;
if (find !== this.find) {
Ember.deprecate('RestAdapter#find has been deprecated and renamed to `findRecord`.');
return this.find(store, type, id, snapshot);
}
return this.ajax(this.buildURL(type.modelName, id, snapshot, 'findRecord'), 'GET');
},
// taken straight from the build-url-mixin and modified
// very slightly to test for logging
urlForQuery: function(query, modelName) {
Ember.debug('urlForQuery is being called');
if (this.urlForFindQuery !== urlForFindQuery) {
Ember.deprecate('BuildURLMixin#urlForFindQuery has been deprecated and renamed to `urlForQuery`.');
return this.urlForFindQuery(query, modelName);
}
return this._buildURL(modelName);
},
// taken straight from the build-url-mixin and modified
// very slightly to test for logging
_buildURL: function(modelName, id) {
Ember.debug('_buildURL is being called');
var url = [];
var host = get(this, 'host');
var prefix = this.urlPrefix();
var path;
if (modelName) {
path = this.pathForType(modelName);
if (path) { url.push(path); }
}
if (id) { url.push(encodeURIComponent(id)); }
if (prefix) { url.unshift(prefix); }
url = url.join('/');
if (!host && url && url.charAt(0) !== '/') {
url = '/' + url;
}
return url;
},
});
Is there an easier way to accomplish what I'm trying to do without overriding adapter methods? And if not, what method(s) do I need to override?
Thanks in advance for your help!
You can use this.store.findQueryOne('invoice', 1, { key: value });
https://github.com/emberjs/data/pull/2584

Categories

Resources