I've been trying to use the url module for node js described here: https://nodejs.org/api/url.html#url_url, but I can't seem to get the simple examples to work. I'd like to be able to build a url, but with the following code,
const URL = require('url');
const apiUrl = new URL('myapi.com/');
apiUrl.searchParams.set('tickers', tickers);
console.log(apiUrl.href);
I run into the error that URL is not a function. I've tried this with the other way the site suggests initializing URL too, as
const { URL } = require('url');
But that causes syntax errors on the first open bracket.
How can I use the url module to actually manipulate urls?
Edit:
In light of MinusFour's suggestion, I'm now up to here:
const URL = require('url').Url;
const apiUrl = new URL('myapi.com/');
console.log(apiUrl);
apiUrl.search = 'tickers=[\'msft\']';
console.log(apiUrl.href);
This does compile and run without throwing an error, but logs
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: null,
query: null,
pathname: null,
path: null,
href: null }
null
Which isn't really what I had hoped for.
It's a property of the module:
const URL = require('url').URL;
If you're using Node 6.x then you have to use URL.parse instead.
Related
I am using jira-client npm to deal with jira rest API , and I am trying to add an attachment to a ticket using addAttachmentOnIssue method, this method requires the key of the issue as a string parameter and also requires ReadStream as the second parameter, I am able to attach a file to a ticket if I followed these steps:
var jiraAPI = require('jira-client');
var jira = new JiraApi({
protocol: "https",
host:"myJiraInstance",
username:"myUserName",
password: "MyToken",
apiVersion: "2",
strictSSL: true,})
then
const fileStream = fs.createReadStream(filePath);
jira.addAttachmentOnIssue(tickeID,fileStream);
As you can see I have the filepath and I attached it but I that is not what I want, I want to create a file from JSON object, without writing this file on the system and then send it
is that possible ?
by using:
var stream = require('stream');
var readable = new stream.Readable(); // new empty stream.Readable
readable.push('some data');
readable.push(null);
jira.addAttachmentOnIssue(tciketID,readable)
I am getting:
Processing of multipart/form-data request failed. Stream ended unexpectedly
the problem is that the required file related information such as filename, knownLength etc. is missing, which is why it fails parsing the stream.
you need to provide file related information manually
as jira-client is using postman-request, you can do that by providing a custom file object like described here:
multipart/form-data (Multipart Form Uploads)
Try this:
var JiraApi = require('jira-client');
var jira = new JiraApi({
protocol: "https",
host: "myJiraInstance",
username: "myUserName",
password: "MyToken",
apiVersion: "2",
strictSSL: true
})
const inputData = JSON.stringify({
someProp: 'some data'
});
var stream = require('stream');
var readable = new stream.Readable();
readable.push(inputData);
readable._read = () => {};
readable.push(null);
// https://www.npmjs.com/package/postman-request#forms
// Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
// Use case: for some types of streams, you'll need to provide "file"-related information manually.
// See the `form-data` README for more information about options: https://github.com/form-data/form-data
const myStreamFile = {
value: readable,
options: {
filename: 'json.json',
contentType: 'application/json',
knownLength: inputData.length
}
}
jira.addAttachmentOnIssue(tciketID, myStreamFile)
I want to use the chrome proxy API. I have this code in my background script but it will not work
const proxyData = []
const fetchProxyData = () => {
axios({
method: "GET",
baseURL: "https://api.getproxylist.com/proxy",
params: {
protocol: "http",
allowsPost: 1,
allowsHttps: 1,
anonimity: "high anonymity"
}
}).then( (response) => {
console.log(response.data)
proxyData.push(response.data)
})
}
fetchProxyData();
var config = {
mode: "fixed_servers",
rules: {
singleProxy: {
host: proxyData.ip,
port: proxyData.port
}
}
}
chrome.proxy.settings.set({
value: config,
scope: "regular"
}, () => {
console.log(`proxy configured with data: ${proxyData}`)
})
I get this error in background page console: background.js:55 Uncaught TypeError: Invalid invocation
I've tried with the example provided with the proxy api documentation and the error will not occur. Maybe it's caused by the config object? To set the proxy as you can see in the code, I'm using an ajax call, maybe is this the problem?
is there any fix?
I have also faced the same problem when I find the solution, it was silly mistake.
I had passed string value to port.
Please make sure you are passing integer value to port
Close. Couple things.
One, you need to fetch your data before calling Chrome's proxy API. And two, your getting the properties for your config from the proxyData array, not the JSON object from your axios call.
You need to do something like this:
const proxyData = [];
const fetchProxyData = () => {
axios({
method: "GET",
baseURL: "https://api.getproxylist.com/proxy",
params: {
protocol: "http",
allowsPost: 1,
allowsHttps: 1,
anonimity: "high anonymity"
}
}).then((response) => {
const {data} = response;
proxyData.push(data);
const config = {
mode: "fixed_servers",
rules: {
singleProxy: {
host: data.ip,
port: data.port
}
}
};
chrome.proxy.settings.set({
value: config,
scope: "regular"
}, () => {
console.log(`proxy configured with data: ${data}`)
});
})
};
fetchProxyData();
What's happening with your code...The properties host and port in singleProxy (in config) are being assigned undefined because those properties don't exist in the array proxyData. They exist in the object returned from your axios call (above, data).
The undefined keys caused Chrome to throw an Invalid Invocation error.
For anyone else getting the Invalid Invocation issue, it seems to me the problem usually lies within the config your passing into Chrome. In particular the types of each key.
In my case, I was passing in the port as a string when it needed to be a number.
In my NextJS app, I have a language selector that's visible on every page. When I select a new language, I just want to replace the current URL by appending a query param lang=en to it.
Here's the function that replaces the URL:
const changeLanguage = (lang: LanguageID) => {
replace({
pathname,
query: { ...query, lang },
});
};
In this example, replace, query and pathname are coming from the next router.
Now, everything works for static routes, but I'm unable to make it work for dynamic routes. For example, I have the following folder structure:
pages
|_customers
|__index.tsx
|__[customerId].tsx
If I'm on http://localhost/customers and I change my language to English, the URL changes to http://localhost/customers?lang=en which is what I want. However, if I'm on http://localhost/customer/1 and I change my language to English, the URL changes to http://localhost/customers/[customerId]?customerId=1&lang=en, instead of the URL I'm expecting http://localhost/customers/1?lang=en.
Now, I know that I could use asPath on the router, and reconstruct the query string object by appending lang to it, but I feel that it's something that should be build into Next. Also, I know it could be easily done with vanilla JS, but it's not the point here.
Am I missing something? Is there an easier way to append query params to a dynamic route without doing a server-side re-rendering?
Thanks
Just add more param to current router then push itself
const router = useRouter();
router.query.NEWPARAMS = "VALUE"
router.push(router)
The solution which doesn't need to send the whole previous route, as replace just replaces what we need to replace, so query params:
const router = useRouter();
router.replace({
query: { ...router.query, key: value },
});
If we want to have this as a link - use it like so:
// ...
const { query } = useRouter();
// ...
<Link
href={{
pathname: router.pathname,
query: { ...query, lang },
}}
passHref
shallow
replace
></Link>
I tried adding my param to the route query and pushing the router itself, as mentioned here, it works, but I got a lot of warnings:
So, I then pushed to / and passed my query params as following:
const router = useRouter();
router.push({ href: '/', query: { myQueryParam: value } });
I hope that works for you too.
I ended up using the solution that I wanted to avoid in the first place, which was to play with the asPath value. Atleast, there's no server-side re-rendering being done since the path is the same.
Here's my updated changeLanguage function (stringifyUrl is coming from the query-string package)
const changeLanguage = (lang: LanguageID) => {
const newPathname = stringifyUrl({ url: pathname, query: { ...query, lang } });
const newAsPath = stringifyUrl({ url: asPath, query: { lang } });
replace(newPathname, newAsPath);
};
If anyone is still looking the answer ,for Next,js ^11.1.2.I hope this helps you out.Use
const router = useRouter();
router.push({ pathname: "/search", query: { key: key } });
An alternative approach when you have dynamic routing in Next.js, and want to do a shallow adjustment of the route to reflect updated query params, is to try:
const router = useRouter()
const url = {
pathname: router.pathname,
query: { ...router.query, page: 2 }
}
router.push(url, undefined, { shallow: true })
This will retreive the current path (router.pathname) and query (router.query) details, and merge them in along with your new page query param. If your forget to merge in the existing query params you might see an error like:
The provided href value is missing query values to be interpolated
properly
In latest version, Next 13, some of the functionality moved to other hooks, which query and path are some of them. You can use useSearchParams to get query and usePathname instead of pathname. By the time I am writing this answer, it does not have a stable version and you can find the beta documents here:
https://beta.nextjs.org/docs/api-reference/use-router
let queryParams;
if (typeof window !== "undefined") {
// The search property returns the querystring part of a URL, including the question mark (?).
queryParams = new URLSearchParams(window.location.search);
// quaeryParams object has nice methods
// console.log("window.location.search", queryParams);
// console.log("query get", queryParams.get("location"));
}
inside changeLanguage,
const changeLanguage = (lang: LanguageID) => {
if (queryParams.has("lang")) {
queryParams.set("lang", lang);
} else {
// otherwise append
queryParams.append("lang", lang);
}
router.replace({
search: queryParams.toString(),
});
};
I am using the default code from https://www.npmjs.com/package/priority-web-sdk
var configuration = {
username: '<username>',
password: '<password>',
url: '<app server url>',
tabulaini: 'tabula.ini',
language: 3,
company: 'demo'
};
priority.login(configuration)
.then(()=> priority.formStart('CUSTOMERS', null, null, 'demo', 1))
.then(form=> form.getRows(1))
.then(rows=> console.log(rows))
.catch(err=> console.log(err));
if i run the code with my config i get no result however if i remove form.getRows(1) and pass the result of formStart i then get a response and the form info is logged to the console i just can't seam to get any more data?
I am using node but if i include the script on the client side and run it that way then it works fine but this is insecure so not a solution.
the soloution was to check if the window is undefined in my code
if it is then we should set it.
if (typeof window === 'undefined') {
global.window = {}
}
In my program I got URL like following format,
when I use the url.parse nothing happen,I need to change the port ,how it suggested do do that ?
The port is after the colon %3 55123 and I need to change it to 8080
http%3A%2F%2Fmo-de73.mo.bmw.corp%3A55123%2Flogin%2Fcallback&client_id=s2.app
The number can be change(any valid port) so I cannot use the replace
Btw there is parser which change the format from %3 to colon and and %2F to slash as standard URL output?
Before you can parse it, you must decode it. You can do this using the built-in decodeURIComponent function.
var url = require('url');
var encodedUrl = 'http%3A%2F%2Fmo-de73.mo.bmw.corp%3A55123%2Flogin%2Fcallback&client_id=s2.app';
var decodedUrl = decodeURIComponent(encodedUrl);
//=> 'http://mo-de73.mo.bmw.corp:55123/login/callback&client_id=s2.app'
var parts = url.parse(decodedUrl);
/* =>
{ protocol: 'http:',
slashes: true,
auth: null,
host: 'mo-de73.mo.bmw.corp:55123',
port: '55123',
hostname: 'mo-de73.mo.bmw.corp',
hash: null,
search: null,
query: null,
pathname: '/login/callback&client_id=s2.app',
path: '/login/callback&client_id=s2.app',
href: 'http://mo-de73.mo.bmw.corp:55123/login/callback&client_id=s2.app' }
*/
parts.port = 8080;
//=> 8080
delete parts.host;
//=> true
url.format(parts);
//=> 'http://mo-de73.mo.bmw.corp:8080/login/callback&client_id=s2.app'
The last part there is a bit of a hack. After you update the port, your parts object will look like this
{
// ...
host: 'mo-de73.mo.bmw.corp:55123',
port: '8080',
hostname: 'mo-de73.mo.bmw.corp',
// ...
}
The hostname is correct, but the host still has the port hard-coded in there. If you just remove the host using delete parts.host, url.format will automatically create the correct host using {hostname}:{port}.
Maybe there's a better way to do it, but at least this should get you started.
Try this
var url="http%3A%2F%2Fmo-de73.mo.bmw.corp%3A55123%2Flogin%2Fcallback&client_id=s2.app";
url=url.replace('%3A55123',":8080");
var decodedUrl = decodeURIComponent(url);
//decodedUrl=http://mo-de73.mo.bmw.corp:8080/login/callback&client_id=s2.app