How to display the second value of array dynamically - json

How would one generically pull the second item under the forecast array without defining the specific 'date' value? Currently, I have to specify the date like "2020-01-27" in order to pull the data.
I tried these but they are not working...
{{ forecast.value[1].hourly[0].weather_code }}
{{ forecast[1].hourly[0].weather_code }}
Here's the data:
{"request":{"type":"Zipcode","query":"90210","language":"en","unit":"f"},"location":{"name":"Beverly Hills","country":"USA","region":"California","lat":"34.087","lon":"-118.412","timezone_id":"America\/Los_Angeles","localtime":"2021-01-26 14:07","localtime_epoch":1611670020,"utc_offset":"-8.0"},"current":{"observation_time":"10:07 PM","temperature":54,"weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"],"weather_descriptions":["Sunny"],"wind_speed":7,"wind_degree":190,"wind_dir":"S","pressure":1016,"precip":0,"humidity":26,"cloudcover":0,"feelslike":54,"uv_index":4,"visibility":10,"is_day":"yes"},"forecast":{"2021-01-26":{"date":"2021-01-26","date_epoch":1611619200,"astro":{"sunrise":"06:54 AM","sunset":"05:19 PM","moonrise":"03:22 PM","moonset":"05:25 AM","moon_phase":"Full Moon","moon_illumination":90},"mintemp":45,"maxtemp":59,"avgtemp":52,"totalsnow":0,"sunhour":10.7,"uv_index":3,"hourly":[{"time":"0","temperature":46,"wind_speed":9,"wind_degree":305,"wind_dir":"NW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":47,"visibility":6,"pressure":1009,"cloudcover":7,"heatindex":46,"dewpoint":27,"windchill":43,"windgust":13,"feelslike":43,"chanceofrain":0,"chanceofremdry":85,"chanceofwindy":0,"chanceofovercast":43,"chanceofsunshine":84,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"300","temperature":46,"wind_speed":7,"wind_degree":306,"wind_dir":"NW","weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0008_clear_sky_night.png"],"weather_descriptions":["Clear"],"precip":0,"humidity":50,"visibility":6,"pressure":1010,"cloudcover":2,"heatindex":46,"dewpoint":28,"windchill":43,"windgust":9,"feelslike":43,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":25,"chanceofsunshine":82,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"600","temperature":46,"wind_speed":6,"wind_degree":329,"wind_dir":"NNW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":50,"visibility":6,"pressure":1012,"cloudcover":1,"heatindex":46,"dewpoint":28,"windchill":43,"windgust":7,"feelslike":43,"chanceofrain":0,"chanceofremdry":89,"chanceofwindy":0,"chanceofovercast":11,"chanceofsunshine":86,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"900","temperature":48,"wind_speed":5,"wind_degree":340,"wind_dir":"NNW","weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"],"weather_descriptions":["Sunny"],"precip":0,"humidity":45,"visibility":6,"pressure":1015,"cloudcover":2,"heatindex":48,"dewpoint":27,"windchill":46,"windgust":6,"feelslike":46,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":23,"chanceofsunshine":86,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":3},{"time":"1200","temperature":55,"wind_speed":4,"wind_degree":294,"wind_dir":"WNW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":33,"visibility":6,"pressure":1016,"cloudcover":1,"heatindex":55,"dewpoint":27,"windchill":55,"windgust":5,"feelslike":55,"chanceofrain":0,"chanceofremdry":91,"chanceofwindy":0,"chanceofovercast":12,"chanceofsunshine":87,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":4},{"time":"1500","temperature":57,"wind_speed":5,"wind_degree":221,"wind_dir":"SW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":31,"visibility":6,"pressure":1016,"cloudcover":3,"heatindex":57,"dewpoint":28,"windchill":57,"windgust":6,"feelslike":57,"chanceofrain":0,"chanceofremdry":86,"chanceofwindy":0,"chanceofovercast":35,"chanceofsunshine":78,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":4},{"time":"1800","temperature":54,"wind_speed":6,"wind_degree":204,"wind_dir":"SSW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":36,"visibility":6,"pressure":1017,"cloudcover":12,"heatindex":54,"dewpoint":28,"windchill":54,"windgust":6,"feelslike":54,"chanceofrain":0,"chanceofremdry":86,"chanceofwindy":0,"chanceofovercast":38,"chanceofsunshine":85,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"2100","temperature":52,"wind_speed":4,"wind_degree":159,"wind_dir":"SSE","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":40,"visibility":6,"pressure":1019,"cloudcover":36,"heatindex":52,"dewpoint":28,"windchill":50,"windgust":5,"feelslike":50,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":40,"chanceofsunshine":80,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1}]}}}

Try this:
const obj = {"request":{"type":"Zipcode","query":"90210","language":"en","unit":"f"},"location":{"name":"Beverly Hills","country":"USA","region":"California","lat":"34.087","lon":"-118.412","timezone_id":"America\/Los_Angeles","localtime":"2021-01-26 14:07","localtime_epoch":1611670020,"utc_offset":"-8.0"},"current":{"observation_time":"10:07 PM","temperature":54,"weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"],"weather_descriptions":["Sunny"],"wind_speed":7,"wind_degree":190,"wind_dir":"S","pressure":1016,"precip":0,"humidity":26,"cloudcover":0,"feelslike":54,"uv_index":4,"visibility":10,"is_day":"yes"},"forecast":{"2021-01-26":{"date":"2021-01-26","date_epoch":1611619200,"astro":{"sunrise":"06:54 AM","sunset":"05:19 PM","moonrise":"03:22 PM","moonset":"05:25 AM","moon_phase":"Full Moon","moon_illumination":90},"mintemp":45,"maxtemp":59,"avgtemp":52,"totalsnow":0,"sunhour":10.7,"uv_index":3,"hourly":[{"time":"0","temperature":46,"wind_speed":9,"wind_degree":305,"wind_dir":"NW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":47,"visibility":6,"pressure":1009,"cloudcover":7,"heatindex":46,"dewpoint":27,"windchill":43,"windgust":13,"feelslike":43,"chanceofrain":0,"chanceofremdry":85,"chanceofwindy":0,"chanceofovercast":43,"chanceofsunshine":84,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"300","temperature":46,"wind_speed":7,"wind_degree":306,"wind_dir":"NW","weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0008_clear_sky_night.png"],"weather_descriptions":["Clear"],"precip":0,"humidity":50,"visibility":6,"pressure":1010,"cloudcover":2,"heatindex":46,"dewpoint":28,"windchill":43,"windgust":9,"feelslike":43,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":25,"chanceofsunshine":82,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"600","temperature":46,"wind_speed":6,"wind_degree":329,"wind_dir":"NNW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":50,"visibility":6,"pressure":1012,"cloudcover":1,"heatindex":46,"dewpoint":28,"windchill":43,"windgust":7,"feelslike":43,"chanceofrain":0,"chanceofremdry":89,"chanceofwindy":0,"chanceofovercast":11,"chanceofsunshine":86,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"900","temperature":48,"wind_speed":5,"wind_degree":340,"wind_dir":"NNW","weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"],"weather_descriptions":["Sunny"],"precip":0,"humidity":45,"visibility":6,"pressure":1015,"cloudcover":2,"heatindex":48,"dewpoint":27,"windchill":46,"windgust":6,"feelslike":46,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":23,"chanceofsunshine":86,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":3},{"time":"1200","temperature":55,"wind_speed":4,"wind_degree":294,"wind_dir":"WNW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":33,"visibility":6,"pressure":1016,"cloudcover":1,"heatindex":55,"dewpoint":27,"windchill":55,"windgust":5,"feelslike":55,"chanceofrain":0,"chanceofremdry":91,"chanceofwindy":0,"chanceofovercast":12,"chanceofsunshine":87,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":4},{"time":"1500","temperature":57,"wind_speed":5,"wind_degree":221,"wind_dir":"SW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":31,"visibility":6,"pressure":1016,"cloudcover":3,"heatindex":57,"dewpoint":28,"windchill":57,"windgust":6,"feelslike":57,"chanceofrain":0,"chanceofremdry":86,"chanceofwindy":0,"chanceofovercast":35,"chanceofsunshine":78,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":4},{"time":"1800","temperature":54,"wind_speed":6,"wind_degree":204,"wind_dir":"SSW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":36,"visibility":6,"pressure":1017,"cloudcover":12,"heatindex":54,"dewpoint":28,"windchill":54,"windgust":6,"feelslike":54,"chanceofrain":0,"chanceofremdry":86,"chanceofwindy":0,"chanceofovercast":38,"chanceofsunshine":85,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"2100","temperature":52,"wind_speed":4,"wind_degree":159,"wind_dir":"SSE","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":40,"visibility":6,"pressure":1019,"cloudcover":36,"heatindex":52,"dewpoint":28,"windchill":50,"windgust":5,"feelslike":50,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":40,"chanceofsunshine":80,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1}]}}}
function getWeatherCode(obj) {
let val;
Object.keys(obj).forEach((e) => {
if(e == 'forecast'){
val = obj[e][formatDate()]['hourly'][1]['weather_code'];
}
});
return val;
}
function formatDate() {
var d = new Date('2021-01-26'),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [year, month, day].join('-');
}
let a = getWeatherCode(obj);
console.log(a);
I harcoded the date but you delete the date and take current date like the following
var d = new Date()
I think this will help for you
Just use {{ getWeatherCode(obj) }}

Like that:
return Object.entries(forecast)[0][1];
Object.entries transforms the object to an array of key-value pairs, [0] grabs the first one, and then [1] grabs value ([0] would be the key).

All I can think of is something like this
const obj = {"request":{"type":"Zipcode","query":"90210","language":"en","unit":"f"},"location":{"name":"Beverly Hills","country":"USA","region":"California","lat":"34.087","lon":"-118.412","timezone_id":"America\/Los_Angeles","localtime":"2021-01-26 14:07","localtime_epoch":1611670020,"utc_offset":"-8.0"},"current":{"observation_time":"10:07 PM","temperature":54,"weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"],"weather_descriptions":["Sunny"],"wind_speed":7,"wind_degree":190,"wind_dir":"S","pressure":1016,"precip":0,"humidity":26,"cloudcover":0,"feelslike":54,"uv_index":4,"visibility":10,"is_day":"yes"},"forecast":{"2021-01-26":{"date":"2021-01-26","date_epoch":1611619200,"astro":{"sunrise":"06:54 AM","sunset":"05:19 PM","moonrise":"03:22 PM","moonset":"05:25 AM","moon_phase":"Full Moon","moon_illumination":90},"mintemp":45,"maxtemp":59,"avgtemp":52,"totalsnow":0,"sunhour":10.7,"uv_index":3,"hourly":[{"time":"0","temperature":46,"wind_speed":9,"wind_degree":305,"wind_dir":"NW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":47,"visibility":6,"pressure":1009,"cloudcover":7,"heatindex":46,"dewpoint":27,"windchill":43,"windgust":13,"feelslike":43,"chanceofrain":0,"chanceofremdry":85,"chanceofwindy":0,"chanceofovercast":43,"chanceofsunshine":84,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"300","temperature":46,"wind_speed":7,"wind_degree":306,"wind_dir":"NW","weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0008_clear_sky_night.png"],"weather_descriptions":["Clear"],"precip":0,"humidity":50,"visibility":6,"pressure":1010,"cloudcover":2,"heatindex":46,"dewpoint":28,"windchill":43,"windgust":9,"feelslike":43,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":25,"chanceofsunshine":82,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"600","temperature":46,"wind_speed":6,"wind_degree":329,"wind_dir":"NNW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":50,"visibility":6,"pressure":1012,"cloudcover":1,"heatindex":46,"dewpoint":28,"windchill":43,"windgust":7,"feelslike":43,"chanceofrain":0,"chanceofremdry":89,"chanceofwindy":0,"chanceofovercast":11,"chanceofsunshine":86,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"900","temperature":48,"wind_speed":5,"wind_degree":340,"wind_dir":"NNW","weather_code":113,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"],"weather_descriptions":["Sunny"],"precip":0,"humidity":45,"visibility":6,"pressure":1015,"cloudcover":2,"heatindex":48,"dewpoint":27,"windchill":46,"windgust":6,"feelslike":46,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":23,"chanceofsunshine":86,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":3},{"time":"1200","temperature":55,"wind_speed":4,"wind_degree":294,"wind_dir":"WNW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":33,"visibility":6,"pressure":1016,"cloudcover":1,"heatindex":55,"dewpoint":27,"windchill":55,"windgust":5,"feelslike":55,"chanceofrain":0,"chanceofremdry":91,"chanceofwindy":0,"chanceofovercast":12,"chanceofsunshine":87,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":4},{"time":"1500","temperature":57,"wind_speed":5,"wind_degree":221,"wind_dir":"SW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":31,"visibility":6,"pressure":1016,"cloudcover":3,"heatindex":57,"dewpoint":28,"windchill":57,"windgust":6,"feelslike":57,"chanceofrain":0,"chanceofremdry":86,"chanceofwindy":0,"chanceofovercast":35,"chanceofsunshine":78,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":4},{"time":"1800","temperature":54,"wind_speed":6,"wind_degree":204,"wind_dir":"SSW","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":36,"visibility":6,"pressure":1017,"cloudcover":12,"heatindex":54,"dewpoint":28,"windchill":54,"windgust":6,"feelslike":54,"chanceofrain":0,"chanceofremdry":86,"chanceofwindy":0,"chanceofovercast":38,"chanceofsunshine":85,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1},{"time":"2100","temperature":52,"wind_speed":4,"wind_degree":159,"wind_dir":"SSE","weather_code":116,"weather_icons":["https:\/\/assets.weatherstack.com\/images\/wsymbols01_png_64\/wsymbol_0004_black_low_cloud.png"],"weather_descriptions":["Partly cloudy"],"precip":0,"humidity":40,"visibility":6,"pressure":1019,"cloudcover":36,"heatindex":52,"dewpoint":28,"windchill":50,"windgust":5,"feelslike":50,"chanceofrain":0,"chanceofremdry":87,"chanceofwindy":0,"chanceofovercast":40,"chanceofsunshine":80,"chanceoffrost":0,"chanceofhightemp":0,"chanceoffog":0,"chanceofsnow":0,"chanceofthunder":0,"uv_index":1}]}}}
function getPropByIndex(obj, index) {
for (let [i,k] of Object.keys(obj).entries()) {
if (i === index) {
return obj[k];
}
}
}
// {{ (getPropByIndex(obj.forecast, 0)).hourly[0].weather_code }}
// or w/o a fn
// {{ Object.entries(obj.forecast)[0][1].hourly[0].weather_code }}

Related

Importing Twilight Data to google sheets

I'm going to be honest, I know very little about any of this and the last time I did any form of programming was in high school 12 years ago.
I am needing to create a schedule for a low budget shoot, however, that is happening in August and I need to send out a daily schedule for the upcoming days as it changes.
I've been trying to work out how to potentially amend this so that it could include the other twilight times as well, but it keeps giving me an error:
// for an idiot, what am I doing wrong? Ideally it would be constructed in such a way that I can use it on future projects as well, placing a screen grab - it would be great if the formula can make reference to other cells and update as those cells update:
screengrab of google sheets
function SolarTimes(lat,long,date,type) {
var response = UrlFetchApp.fetch("https://api.sunrise-sunset.org/json?lat="+lat+"&lng="+long+"&date="+date);
var json = response.getContentText();
var data = JSON.parse(json);
var sunrise = data.results.sunrise;
var sunset = data.results.sunset;
var civil_dawn = data.results.civil_twilight_begin;
var civil_dusk = data.results.civil_twilight_end;
var nautical_dawn = data.results.nautical_twilight_begin;
var nautical_dusk = data.results.nautical_twilight_end;
var day_length = data.results.day_length;
{ if (type == "Sunrise")
return sunrise;
else if (type == "Sunset")
return sunset;
else if (type = "Civil_Dawn")
return civildawn;
else if (type == "Civil_Dusk")
return civildusk;
else if (type == "Nautical_Dawn")
return nauticaldawn;
else if (type == "Nautical_Dusk")
return nauticaldusk;
else
return day_length};
}
Here's an implementation that handles numeric dates and validates arguments.
/**
* Gets the sunrise or sunset time or day length at a location on a date.
*
* #param {36.7201600} latitude The north–south position to use.
* #param {-4.4203400} longitude The east-west position to use.
* #param {"sunrise"} type One of "all", "sunrise", "sunset", "civil_dawn", "civil_dusk", "nautical_dawn", "nautical_dusk" or "day_length".
* #param {D2} date Optional. Defaults to the current date.
* #return {String|String[][]} The requested time as a text string. With "all", an array of types and times.
* #customfunction
*/
function Daylight(latitude, longitude, type, date) {
// see https://stackoverflow.com/a/72675674/13045193
// note: api.sunrise-sunset.org/json does not handle polar night nor midnight sun correctly
'use strict';
const [lat, lng, key, dateString] = _validate(arguments);
const url = `https://api.sunrise-sunset.org/json?lat=${lat}&lng=${lng}&date=${dateString}`;
const { results, status } = JSON.parse(UrlFetchApp.fetch(url).getContentText());
if (key === 'all') {
return Object.keys(results).map(key => [key, results[key]]);
}
return results[key] ?? NaN;
/**
* Validates function arguments.
*/
function _validate(args) {
if (args.length < 3 || args.length > 4) {
throw new Error(`Wrong number of arguments to Daylight. Expected 3 or 4 arguments, but got ${args.length} arguments.`);
}
const lat = Number(latitude);
const lng = Number(longitude);
if (latitude === '' || Number.isNaN(lat) || lat > 90 || lat < -90 || longitude === '' || Number.isNaN(lng) || lng > 180 || lng < -180) {
throw new Error(`Daylight expected a numeric latitude [-90, 90] and longitude [-180, 180], but got the ${typeof latitude} '${latitude}' and the ${typeof longitude} '${longitude}'.`);
}
return [
lat,
lng,
type.toLowerCase().replace('dawn', 'twilight_begin').replace('dusk', 'twilight_end'),
_dateToISO8601(date),
];
}
/**
* Parses a date or string to an ISO8601 date string.
*/
function _dateToISO8601(date) {
if (date === '' || (date == null)) {
date = new Date();
}
if (typeof date === 'string') {
date = new Date(Date.parse(date));
}
if (Object.prototype.toString.call(date) !== '[object Date]') {
throw new Error(`Daylight expected a date, but '${date}' is a ${typeof date}.`);
}
return Utilities.formatDate(date, SpreadsheetApp.getActive().getSpreadsheetTimeZone(), 'yyyy-MM-dd');
}
}
The code looks more or less fine. But the cell contains the little error I think. It should be thusly:
=Solartimes($G$3,$H$3,text($B$6,"yyyy-mm-dd"),C6)
As for the code I'd propose to use switch/case for this case:
function SolarTimes(lat,long,date,type) {
var response = UrlFetchApp.fetch("https://api.sunrise-sunset.org/json?lat="+lat+"&lng="+long+"&date="+date);
var json = response.getContentText();
var {results} = JSON.parse(json);
switch (type.toLowerCase()) {
case ('sunrise'): return results.sunrise;
case ('sunset'): return results.sunset;
case ('civil_dawn'): return results.civil_twilight_begin;
case ('civil_dusk'): return results.civil_twilight_end;
case ('nautical_dawn'): return results.nautical_twilight_begin;
case ('nautical_dusk'): return results.nautical_twilight_end;
case ('day_length'): return results.day_length;
}
return '--';
}
It works about the the same way but looks cleaner.
Just in case. The line:
var {results} = JSON.parse(json);
is the same as:
var data = JSON.parse(json);
var results = data.results;
See:
Destructuring assignment

Getting two values from a Vue <select> #change event

I have a drop-down <select> element that uses an array with key:value pairs. I'd like for the dropdown to only display values, but upon selection have the #change pass on both the value and the key.
<select
#change="
formChanged(
$event,
$event.target.selectedIndex,
$event.target.value,
$event.target.key
)
"
name="selectForm"
id="selectForm"
required
>
<option
v-for="(option, id) in getFormSelectArray()"
:key="id" :value="option"
>
{{ option }}
</option>
</select>
My function called through #change:
formChanged(event, selectedIndex, value, id): void {
console.log(
'Form Selection Changed: ' + event + ' ' + selectedIndex + ' ' + value, + ' ' + id
);
}
My data array generating function:
public getFormSelectArray() {
// Mapping IDs to Names
const names = 'a, b, c';
const ids = '123, 456, 789';
let i;
let currentKey;
let currentVal;
const result = {}
for (i = 0; i < ids.split(',').length; i++) {
currentKey = ids.split(',')[i];
currentVal = names.split(',')[i];
result[currentKey] = currentVal;
}
for (const key in result) {
const value = result[key];
}
return result;
}
My output:
Form Selection Changed: [object Event] 0 a NaN
How do I output the ID of 123 instead of NaN?
I think you should use #input instead of #change.

As3 set set end-Date using value in array

i want to make end-subscription after admin enter the value/date into text_box then it will push to array,after that i want when time reach the date that been enter the application will exit.
But I don't know the method.
below is my code
var my_date:Date;
var my_timer:Timer=new Timer(1000);
my_timer.addEventListener(TimerEvent.TIMER, onTimer);
my_timer.start();
var tarikh:Array = new Array();
tarikh.hari = [0];
tarikh.bulan = [1];
tarikh.tahun = [2];
my_date = new Date();
function onTimer(e:TimerEvent):void
{
my_date = new Date();
//trace(my_date.date + ":" + my_date.month + " : " + my_date.fullYear );
}
btnCuba.addEventListener(MouseEvent.CLICK,MMM);
function MMM (event:MouseEvent):void
{
tarikh.hari = String(hari.text);
tarikh.bulan = String(bulan.text);
tarikh.tahun = String(tahun.text) ;
tarikh.push(hari,bulan,tahun);
setHours();
trace(tarikh.hari + "" + tarikh.bulan + "" + tarikh.tahun);
}
function setHours():void
{
if (my_date.date == tarikh.hari && my_date.month == tarikh.hari && my_date.fullYear == tarikh.hari && && my_date.minutes == 01)
{
NativeApplication.nativeApplication.exit();
}
else
{
my_timer.start();
}
}
tarikh is an array. Arrays are assigned to using the array index access operator. When you want to store data in an array, you do it like this:
array_name[index] = value
or in this case,
tarikh[0] = hari;
Looking at the code, tarikh seems to mean date, hari, bulan and tahun seem to mean day, month and year. The Date class doesn't have these properties (you'll have to translate them to English); alternatively, an easier method of comparing dates is just to compare the getTime() function returns by the two date objects:
if(my_date.getTime() == tarikh.getTime()) { NativeApplication.nativeApplication.exit(); }
The problem is that tarikh is not a Date object now, but is an Array. Arrays don't have any properties by themselves (apart from length), so maybe you're looking for a tarikh being a Date object? You could try making tarikh as a Date object with the values like so:
tarikh = new Date(hari.text + " " + bulan.text + " " + tahun.text); if the text values are letters (like Tue Feb 3 2005), otherwise if they are numbers or integers then try casting it and using it in the appropriate parameter.

Assign JSON value to variable based on value of a different key

I have this function for extracting the timestamp from two JSON objects:
lineReader.on('line', function (line) {
var obj = JSON.parse(line);
if(obj.Event == "SparkListenerApplicationStart" || obj.Event == "SparkListenerApplicationEnd") {
console.log('Line from file:', obj.Timestamp);
}
});
The JSON comes from a log file(not JSON) where each line represents an entry in the log and each line also happens to be in JSON format on its own.
The two objects represent the start and finish of a job. These can be identified by the event key(SparkListenerApplicationStart and SparkListenerApplicationEnd). They also both contain a timestamp key. I want to subtract the end time from the start time to get the duration.
My thinking is to assign the timestamp from the JSON where Event key = SparkListenerApplicationStart to one variable and assign the timestamp from the JSON where Event key = SparkListenerApplicationEnd to another variable and subtract one from the other. How can I do this? I know I can't simply do anything like:
var startTime = if(obj.Event == "SparkListenerApplicationStart"){
return obj.Timestamp;
}
I'm not sure if I understood, but if are reading rows and want get the Timestamp of each row I would re-write a new object;
const collection = []
lineReader.on('line', function (line) {
var obj = JSON.parse(line);
if(obj.Event == "SparkListenerApplicationStart" || obj.Event == "SparkListenerApplicationEnd") {
// console.log('Line from file:', obj.Timestamp);
collection.push(obj.Timestamp)
}
});
console.log(collection);
Where collection could be a LocalStorage, Global Variable, or something alike.
Additional info
With regard to my comment where I queried how to identify the start and end times, I ended up setting start as the smallest value and end as the largest. Here is my final code:
const collection = []
lineReader.on('line', function (line) {
var obj = JSON.parse(line);
if((obj.Event == "SparkListenerApplicationStart" || obj.Event == "SparkListenerApplicationEnd")) {
collection.push(obj.Timestamp);
if(collection.length == 2){
startTime = Math.min.apply(null, collection);
finishTime = Math.max.apply(null, collection);
duration = finishTime - startTime;
console.log(duration);
}
}
});

Knockout.js format date item

In my view I wish to display a knockout.js binded field that contains a date. It is just a display field and not an input field. Something like below when basemodel.actionDate = ko.observable()
<p class="display-field" data-bind="text: baseModel.actionDate"/>
However this is displayed as follows:
2013-06-17T11:56:18.4537687Z
What is the easiest way to format this dd mm yyyy. eg: 17 June 2013?
I recommend the moment.js date formatting library.
Using it, you can do something like this in your view:
<p class="display-field" data-bind="text: moment(baseModel.actionDate()).format('LL')"/>
Either make sure the service output it in a correct format, or format in client side
If you want todo it client side then you can parse the ISO date string into a Date object and then use jQuery globalize to format it to desired format.
I use KO extenders for this
http://jsfiddle.net/vRf5B/42/
ko.extenders.date = function(target, format) {
return ko.computed({
read: function() {
var value = target();
if(typeof value === "string") {
value = new Date(value);
}
format = typeof format === "string" ? format: undefined;
value = Globalize.format(value, format);
return value;
},
write: target
});
}
update
I got a question on my blog how to retrieve the raw date value
It can be done my exposing the raw value on the computed like
http://jsfiddle.net/vRf5B/91/
Declare format function:
Date.prototype.toFormattedDate = function () {
var dd = this.getDate();
if (dd < 10) dd = '0' + dd;
var mm = this.getMonth() + 1;
if (mm < 10) mm = '0' + mm;
var yyyy = this.getFullYear();
/* change format here */
return String(mm + "/" + dd + "/" + yyyy);
};
And use it with the date strings as:
<span data-bind="text: new Date(TaxAuthority.RegDate).toFormattedDate()"></span>
I had some issues (I think) with the mapping plugin trying to use the extender. Since I'm only displaying dates and not allowing them to be edited I prefer to just use a binding handler like this:
Shipped on <span data-bind="date: shipDt"></span>
Here's the handler:
ko.bindingHandlers.date =
{
update: function (element, valueAccessor: () => any, allBindingsAccessor: any)
{
return ko.bindingHandlers.text.update(element, function ()
{
var value: any = ko.utils.unwrapObservable(valueAccessor());
if (value == null)
{
return null;
}
if (typeof value === "string")
{
value = new Date(value);
}
return value.toShortDateString();
}, allBindingsAccessor, null, null);
}
};
I chose to add a prototype to Date object like this (and call toShortDateString on the Date object created in the handler)- but you can replace the logic above with Globalize or whatever you prefer.
Date.prototype.toShortDateString = function ()
{
return (this.getMonth() + 1) + "/" + this.getDate() + "/" + this.getFullYear();
};
If you are referencing moment.js then I would actually format in the knockout model.
var BiographicViewModel = function (person) {
this.FirstName = ko.observable(person.first_name);
this.LastName = ko.observable(person.last_name);
this.DOB = ko.observable(moment(person.birth_date).format("MM/DD/YYYY"));
this.Gender = ko.observable(person.gender);
this.Country = ko.observable(person.country);
this.City = ko.observable(person.city);
};