I wrote a function to retrieve Yahoo! Finance data for certain stocks. The sheet was, however, generating too many URL calls to Yahoo! and I was regularly restricted for the rest of the day.
Since the data that I am retrieving is not expected to change often anyway, the solution seems to be using Google Sheets cache to store any values that are retrieved for 7 days before querying live again.
The code is as follows, and a link to the spreadsheet I'm using is below:
function yahoofinance(ticker)
{
var url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(ticker) + '?modules=price,assetProfile,summaryDetail';
var cache = CacheService.getDocumentCache();
var cached = cache.get(url);
if (cached != null)
{
var object = cached;
var source = 'cache';
}
else
{
var response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
var responseCode = response.getResponseCode();
if (responseCode === 200)
{
var object = JSON.parse(response.getContentText());
var source = 'live';
cache.put(url, "cached", 21600);
properties.setProperty(url, object);
}
}
var fwdPE = object.quoteSummary.result[0]?.summaryDetail?.forwardPE?.fmt || '-';
var sector = object.quoteSummary.result[0]?.assetProfile?.sector || '-';
var mktCap = object.quoteSummary.result[0]?.price?.marketCap?.fmt || '-';
return [[source, fwdPE, sector, mktCap]];
}
Link to the Google Sheet
The problem is that any function call gets the same error:
Error
TypeError: Cannot read property 'result' of undefined (line 28).
Line 28 is:
var fwdPE = object.quoteSummary.result[0]?.summaryDetail?.forwardPE?.fmt || '-';
As far as I understand, object (and thus result[]) should be available.
What am I doing wrong. Why is this error generated?
Am Implementing Google cache correctly? What do I need to improve?
Any help is greatly appreciated!
Try it this way
function yahoofinance(ticker) {
const url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(ticker) + '?modules=price,assetProfile,summaryDetail';
const cache = CacheService.getDocumentCache();
const cached = cache.get("response");
let object = {};
if (cached) {
object.response = cached;
object.source = 'cache';
} else {
let response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
if (response.getResponseCode() == 200) {
object.response = JSON.parse(response.getContentText());
object.source = 'live';
cache.put("response", cached, 21600);
}
}
let fwdPE = object.response.quoteSummary.result[0]?.summaryDetail?.forwardPE?.fmt || '-';
let sector = object.response.quoteSummary.result[0]?.assetProfile?.sector || '-';
let mktCap = object.response.quoteSummary.result[0]?.price?.marketCap?.fmt || '-';
return [[object.source, fwdPE, sector, mktCap]];
}
While using some code to get an image url, I have ran into some issues, the code is saying url.match is not a function.
Any help would be great!
function youtube(url = $w('#input1')) {
var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;
var match = url.match(regExp);
if (match && match[1].length === 11) {
let urllink = match[1];
let imagelink = "http:\/\/img.youtube.com\/vi\/" + urllink + "\/hqdefault.jpg\"";
console.log(imagelink);
} else {
//Nothing
}
}
Thanks
According to wix documentation, $w function selects and returns elements from a page.
If you have an input on the page with id set to input1 (you are trying to select it by calling $w('#input1')) than the variable url holds handle for the input, not the value of the input.
So try to get the value from it (like url = url.value, or just url = $w('#input1').value), and after than call url.match(regExp);.
Edit your function like this:
function youtube(url = $w('#input1')) {
var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;
url = url.value;
var match = url.match(regExp);
if (match && match[1].length === 11) {
let urllink = match[1];
let imagelink = "http:\/\/img.youtube.com\/vi\/" + urllink + "\/hqdefault.jpg\"";
console.log(imagelink);
}
else {
//Nothing
}
}
I'm using jQuery 1.12. I want to replace a query string parameter in my window's URL query string, or add the parameter if doesn't exist. I tried the below:
new_url = window.location.href.replace( /[\?#].*|$/, "?order_by=" + data_val )
window.location.href = new_url
but what I'm discovering is that this wipes out all previous parameters in the query string, which I don't want. If the query string is:
?a=1&b=2
I would want the new query string to be:
?a=2&b=2&order_by=data
and if the query string was:
?a=2&b=3&order_by=old_data
it would become:
?a=2&b=3&order_by=data
You could use a jQuery plugin to do the all the heavy lifting for you. It will parse the query string, and also reconstruct the updated query string for you. Much less code to deal with.
Plugin Download Page
Github Repo
// URL: ?a=2&b=3&order_by=old_data
var order_by = $.query.get('order_by');
//=> old_data
// Conditionally modify parameter value
if (order_by) {
order_by = “data”;
}
// Inject modified parameter back into query string
var newUrl = $.query.set(“order_by”, order_by).toString();
//=> ?a=2&b=3&order_by=data
For those using Node.js, there is a package for this available in NPM.
NPM Package
Github Repo
var queryString = require('query-string');
var parsed = queryString.parse('?a=2&b=3&order_by=old_data'); // location.search
// Conditionally modify parameter value
if (parsed.order_by) {
parsed.order_by = 'data';
}
// Inject modified parameter back into query string
const newQueryString = queryString.stringify(parsed);
//=> a=2&b=3&order_by=data
A good solution ought to handle all of the following:
A URL that already has an order_by query parameter, optionally with whitespace before the equals sign. This can be further divided into cases where the order_by appears at the start, middle or end of the query string.
A URL that doesn't already have and order_by query parameter but does already have a question mark to delimit the query string.
A URL that doesn't already have and order_by query parameter and doesn't already have a question mark to delimit the query string.
The following will handle the cases above:
if (/[?&]order_by\s*=/.test(oldUrl)) {
newUrl = oldUrl.replace(/(?:([?&])order_by\s*=[^?&]*)/, "$1order_by=" + data_val);
} else if (/\?/.test(oldUrl)) {
newUrl = oldUrl + "&order_by=" + data_val;
} else {
newUrl = oldUrl + "?order_by=" + data_val;
}
as demonstrated below:
getNewUrl("?a=1&b=2");
getNewUrl("?a=2&b=3&order_by=old_data");
getNewUrl("?a=2&b=3&order_by = old_data&c=4");
getNewUrl("?order_by=old_data&a=2&b=3");
getNewUrl("http://www.stackoverflow.com");
function getNewUrl(oldUrl) {
var data_val = "new_data";
var newUrl;
if (/[?&]order_by\s*=/.test(oldUrl)) {
newUrl = oldUrl.replace(/(?:([?&])order_by\s*=[^?&]*)/, "$1order_by=" + data_val);
} else if (/\?/.test(oldUrl)) {
newUrl = oldUrl + "&order_by=" + data_val;
} else {
newUrl = oldUrl + "?order_by=" + data_val;
}
console.log(oldUrl + "\n...becomes...\n" + newUrl);
}
something like this?
let new_url = "";
if (window.location.search && window.location.search.indexOf('order_by=') != -1) {
new_url = window.location.search.replace( /order_by=\w*\d*/, "order_by=" + data_val);
} else if (window.location.search) {
new_url = window.location.search + "&order_by=" + data_val;
} else {
new_url = window.location.search + "?order_by=" + data_val;
}
window.location.href = new_url;
function addOrReplaceOrderBy(newData) {
var stringToAdd = "order_by=" + newData;
if (window.location.search == "")
return window.location.href + stringToAdd;
if (window.location.search.indexOf('order_by=') == -1)
return window.location.href + stringToAdd;
var newSearchString = "";
var searchParams = window.location.search.substring(1).split("&");
for (var i = 0; i < searchParams.length; i++) {
if (searchParams[i].indexOf('order_by=') > -1) {
searchParams[i] = "order_by=" + newData;
break;
}
}
return window.location.href.split("?")[0] + "?" + searchParams.join("&");
}
window.location.href = addOrReplaceOrderBy("new_order_by");
A little long but I think it works as intended.
You can remove parameter from query string using URLSearchParams https://developer.mozilla.org/ru/docs/Web/API/URLSearchParams?param11=val
It is not yet supported by IE and Safari, but you can use it by adding polyfill https://github.com/jerrybendy/url-search-params-polyfill
And for accessing or modifying query part of the URI you should use "search" property of the window.location.
Working code example:
var a = document.createElement("a")
a.href = "http://localhost.com?param1=val¶m2=val2¶m3=val3#myHashCode";
var queryParams = new URLSearchParams(a.search)
queryParams.delete("param2")
a.search = queryParams.toString();
console.log(a.href);
Try this:
For reading parameters:
const data = ['example.com?var1=value1&var2=value2&var3=value3', 'example.com?a=2&b=2&order_by=data']
const getParameters = url => {
const parameters = url.split('?')[1],
regex = /(\w+)=(\w+)/g,
obj = {}
let temp
while (temp = regex.exec(parameters)){
obj[temp[1]] = decodeURIComponent(temp[2])
}
return obj
}
for(let url of data){
console.log(getParameters(url))
}
For placing only this parameters:
const data = ['example.com?zzz=asd']
const parameters = {a:1, b:2, add: "abs"}
const setParameters = (url, parameters) => {
const keys = Object.keys(parameters)
let temp = url.split('?')[0] += '?'
for (let i = 0; i < keys.length; i++) {
temp += `${keys[i]}=${parameters[keys[i]]}${i == keys.length - 1 ? '' : '&'}`
}
return temp
}
for (let url of data){
console.log(setParameters(url, parameters))
}
And finaly for inserting (or replace while exists)
const data = ['example.com?a=123&b=3&sum=126']
const parameters = {order_by: 'abc', a: 11}
const insertParameters = (url, parameters) => {
const keys = Object.keys(parameters)
let result = url
for (let i = 0; i < keys.length; i++){
if (result.indexOf(keys[i]) === -1) {
result += `&${keys[i]}=${encodeURIComponent(parameters[keys[i]])}`
} else {
let regex = new RegExp(`${keys[i]}=(\\w+)`)
result = result.replace(regex, `&${keys[i]}=${encodeURIComponent(parameters[keys[i]])}`)
}
}
return result
}
for (let url of data){
console.log(insertParameters(url, parameters))
}
Hope this works for you ;)
After using function just replace window.location.href
This small function could help.
function changeSearchQueryParameter(oldParameter,newParameter,newValue) {
var parameters = location.search.replace("?", "").split("&").filter(function(el){ return el !== "" });
var out = "";
var count = 0;
if(oldParameter.length>0) {
if(newParameter.length>0 && (newValue.length>0 || newValue>=0)){
out += "?";
var params = [];
parameters.forEach(function(v){
var vA = v.split("=");
if(vA[0]==oldParameter) {
vA[0]=newParameter;
if((newValue.length>0 || newValue>=0)) {
vA[1] = newValue;
}
} else {
count++;
}
params.push(vA.join("="));
});
if(count==parameters.length) {
params.push([newParameter,newValue].join("="));
}
params = params.filter(function(el){ return el !== "" });
if(params.length>1) {
out += params.join("&");
}
if(params.length==1) {
out += params[0];
}
}
} else {
if((newParameter.length>0) && (newValue.length>0 || newValue>=0)){
if(location.href.indexOf("?")!==-1) {
var out = "&"+newParameter+"="+newValue;
} else {
var out = "?"+newParameter+"="+newValue;
}
}
}
return location.href+out;
}
// if old query parameter is declared but does not exist in url then new parameter and value is simply added if it exists it will be replaced
console.log(changeSearchQueryParameter("ib","idx",5));
// add new parameter and value in url
console.log(changeSearchQueryParameter("","idy",5));
// if no new or old parameter are present url does not change
console.log(changeSearchQueryParameter("","",5));
console.log(changeSearchQueryParameter("","",""));
Maybe you could try tweaking the regular expression to retrieve only the values you're looking for, then add or update them in a helper function, something like this:
function paramUpdate(param) {
var url = window.location.href,
regExp = new RegExp(param.key + '=([a-z0-9\-\_]+)(?:&)?'),
existsMatch = url.match(regExp);
if (!existsMatch) {
return url + '&' + param.key + '=' + param.value
}
var paramToUpdate = existsMatch[0],
valueToReplace = existsMatch[1],
updatedParam = paramToUpdate.replace(valueToReplace, param.value);
return url.replace(paramToUpdate, updatedParam);
}
var new_url = paramUpdate({
key: 'order_by',
value: 'id'
});
window.location.href = new_url;
Hope it works well for your needs!
To use Regex pattern, I prefer this one:
var oldUrl = "http://stackoverflow.com/";
var data_val = "newORDER" ;
var r = /^(.+order_by=).+?(&|$)(.*)$/i ;
var newUrl = "";
var matches = oldUrl.match(r) ;
if(matches===null){
newUrl = oldUrl + ((oldUrl.indexOf("?")>-1)?"&":"?") + "order_by=" + data_val ;
}else{
newUrl = matches[1]+data_val+matches[2]+matches[3] ;
}
conole.log(newUrl);
If no order_by exist, matches is null and order_by=.. should come after ? or & (if other parameters exist, new one needs &).
If order_by exist, matches has 3 items, see here
Based on AVAVT´s answer I improved it so it takes any key, and I also fixed the missing "?" if there was no querystring
function addOrReplace(key, value) {
var stringToAdd = key+"=" + value;
if (window.location.search == "")
return window.location.href + '?'+stringToAdd;
if (window.location.search.indexOf(key+'=') == -1)
return window.location.href + stringToAdd;
var newSearchString = "";
var searchParams = window.location.search.substring(1).split("&");
for (var i = 0; i < searchParams.length; i++) {
if (searchParams[i].indexOf(key+'=') > -1) {
searchParams[i] = key+"=" + value;
break;
}
}
return window.location.href.split("?")[0] + "?" + searchParams.join("&");
}
usuage:
window.location.href = addOrReplace('order_by', 'date_created');
if you would not want to reload the page you can use pushState Api
if (history.pushState) {
var newurl = addOrReplace('order_by', 'date_created');
window.history.pushState({path:newurl},'',newurl);
}
function myFunction() {
var str = "https://www.citicards.com/cards/credit/application/flow.action?app=UNSOL&HKOP=828cca70910b4fe25e118bd0b59b89c3c7c560df877909495d8252d20026cf8d&cmp=afa|acquire|2003|comparecards&ranMID=44660&ranEAID=2759285&ProspectID=516511657A844EF3A6F0C2B1E85FEFB0&ID=3000";
var res = str.split("&");
var myKey;
if (!str.includes("ranSiteID")) {
console.log("key not found ");
res.push('ranSiteID=samplearsdyfguh.090-nuvbknlmc0.gvyhbjknl')
console.log(res.join("&"));
} else {
res.map(function(key) {
console.log("my keys", key);
if (key.includes("ranSiteID")) {
console.log("my required-->key", key);
mykey = key.split("=");
console.log(mykey);
}
})
}
document.getElementById("demo").innerHTML = res;
}
<!DOCTYPE html>
<html>
<body>
<p>Click the button to display the array values after the split.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
</body>
</html>
I'm supposed to create a functions to test a URL for validity then functions to look for and return parts of the URL string based on location of certain characters (position would be unknown). FYI, I'm very new to programming but have been searching and trying many answers. My latest attempt uses below format (found in an answer) but still can not get anything but an empty string to display when I call the function.
When I run this in Chrome, and enter "http://www.niagaracollege.ca" or "http://lego.ca" even though I am entering a valid URL, I get a return of false.
function validURL(userInput)
{
input = new String(userInput);
if (input.indexOf("://") != -1 && input.lastIndexOf(".") != -1)
return true;
else
return false;
}
function findProtocol(userInput)
{
input = new String(userInput);
var result = input.substring(0, input.indexOf("://"));
return result;
}
function findServer(userInput)
{
input = new String(userInput);
var result = input.substring(input.indexOf("://") + 1 ,input.lastIndexOf("."));
return result;
}
function findDomain(userInput)
{
input = new String(userInput);
var result = input.substring(input.lastIndexOf(".") + 1);
return result;
}
function btnReadURL_onclick()
{
var userInput = document.getElementById("txtURL").value;
var outputBox = document.getElementById("txtOutput");
var URL = validURL(userInput);
if (URL = true)
{
var Part1 = findProtocol(userInput);
var Part2 = findServer(userInput);
var Part3 = findDomain(userInput);
outputBox.value = "Protocol: " + Part1 + "\nServer: " + Part2 +
"\nDomain: " + Part3;
}
else (URL == true)
outputBox.value = "Invalid URL";
}
Use a debugger to find out what you are getting in the userInput. The code is fine. It should work. See sample code below.
test = function() {
var test = "http://Test 2"
alert(test.substring(0, test.indexOf("://")))
}
You need to pass the value to the findProtocol method rather than DOM element
Replace
var userInput = document.getElementById("txtURL");
by
var userInput = document.getElementById("txtURL").value;
and replace
if (URL = true)
with
if( URL == true )
var api = "/self/{code}/my/{id}";
var code = "GHUYFUYI";
var id = 12346;
Hi i'm new to Jquery...any help is appreciated.
Using above API path data how can we generate URL like given below using JQuery?
Thanks in advance....
Result:
/self/GHUYFUYI/my/12346
var api = "/self/{0}/my/{1}";
var array = new Array("GHUYFUYI",12345);
for (var i = 0; i < array.length; i++) {
api = api.replace("{"+i+"}",arr[i]);
}
cosole.log(api);
you can do something like this.
You don't need jQuery for this. Just plain old Javascript...
var api = "/self/{code}/my/{id}";
var code = "GHUYFUYI";
var id = 12346;
api = api.replace("{code}", code).replace("{id}", id);
Your best bet would be to use regular expressions. Here's a simple example:
var api = "/self/{code}/my/{id}";
var code = "GHUYFUYI";
var id = 12346;
api = api.replace(/{code}/, code).replace(/{id}/, id);
You can use the javascript function Replace (http://www.w3schools.com/jsref/jsref_replace.asp)
api = api.replace("{code}", code).replace("{id}", id);
Enhance string prototype
if (!String.prototype.format) {
String.prototype.format = function() {
var str = this.toString();
if (!arguments.length)
return str;
var args = typeof arguments[0],
args = (("string" == args || "number" == args) ? arguments : arguments[0]);
for (arg in args)
str = str.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
return str;
}
}
Usage
var formatData = {
code:"GHUYFUYI",
id:12346
};
var api = "/self/{code}/my/{id}".format(formatData);
Credits: Gabriel Nahmias