Local Storage Not Working As Expected - javascript

I built an app that I then built with PhoneGap Build.THe purpose is for it to run a code (starts at var Quotes once per day when the app is loaded).
When debugging why it wasn't working I noticed that in console I was getting back my message "Local storage didn't work". This means that my initial localstorage.getItem which is supposed to make sure the local storage can be read is returning null. So my code never gets executed.
What am I doing wrong?
function onDeviceReady() { //Do something when the app on device is loaded
var localVal = localStorage.getItem('DateOpened');
if(localVal == null){
console.log("LocalStorage did not work...")}
else
{
var tempd = new Date(); //Get today's date
var str = tempd.getDay() + tempd.getMonth() + tempd.getFullYear();
if(localVal.localeCompare(str) == -1)
{
var Quotes = [];
var ID = [];
var Tag = [];
var seen = [];
localStorage.setItem('DateOpened',str);
console.log("The App Ran, you can get a new fat tomorrow");
console.log("Todays date:" + str);
}
}
}

Initially, there will be no DateOpened item in local storage, so your code will follow the "did not work" branch, because getItem returns null for things that don't exist. That branch never sets anything in DateOpened, so...you'll always follow that branch.
The fix is not to skip over your code setting DateOpened if the device has local storage.
There's also an unrelated problem: Your var str = tempd.getDay() + tempd.getMonth() + tempd.getFullYear() does not produce a string, it produces a number formed by adding those values together, since they're all numbers. Your later localeCompare will fail because it's not a string. You also have the fields in the wrong order for a meaningful textual comparison — you need year first, then month, then day.
Here's a minimal fix, see comments:
function onDeviceReady() {
var tempd = new Date();
// Note that by adding strings in there, we end up with a string instead of adding.
// Note the order: Year first, then month, then day.
// Also, since we display it, we put separators in and add 1 to month (since Jan = 0).
var str = tempd.getFullYear() + "-" + (tempd.getMonth() + 1) + "-" + tempd.getDay();
var localVal = localStorage.getItem('DateOpened');
// If we have no stored value, or it's more than a day old by your definition,
// do your stuff and store the new date
if (localVal == null || localVal.localeCompare(str) < 0) {
var Quotes = [];
var ID = [];
var Tag = [];
var seen = [];
localStorage.setItem('DateOpened', str);
console.log("The App Ran, you can get a new fat tomorrow");
console.log("Todays date:" + str);
}
}

I think this is help full for you.
function onDeviceReady() { //Do something when the app on device is loaded
var localVal = localStorage.getItem('DateOpened');
if (typeof(DateOpened) == "undefined")
console.log("LocalStorage did not work...")}
else
{
var tempd = new Date(); //Get today's date
var str = tempd.getDay() + tempd.getMonth() + tempd.getFullYear();
var allRecords=JSON.parse(localStorage.getItem("DateOpened"));
if(allRecords == -1)
{
var Quotes = [];
var ID = [];
var Tag = [];
var seen = [];
localStorage.setItem('DateOpened',str);
console.log("The App Ran, you can get a new fat tomorrow");
console.log("Todays date:" + str);
}
}
}

Related

Returning future weekday excluding holidays

I should preface by saying I know nothing about scripting. I found this script online that fit my needs, so I was able to re-purpose it for my project. Anyway, this script takes Google form submissions, populates a Google doc template, that template gets copied, converted to PDF, and placed in a specific folder on my Google Drive.
So my question is, I have a simple line that pulls the current date when the script gets run, but I also need some code that can calculate the current date plus 5 weekdays (which should exclude weekends), but I also need it to exclude defined holidays. Any help would be greatly appreciated.
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set as variables
var email_address = "";
var job_name = e.values[1];
var ship_to = e.values[11];
var address = e.values[12];
var order_count = e.values[7];
var program = e.values[2];
var workspace = e.values[3];
var offer = e.values[4];
var sort_1 = e.values[5];
var sort_2 = e.values[6];
var print_services = e.values[10];
var priority = e.values[13];
var notes = e.values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
You can use the below function to get future date which excludes weekends and if any holiday declared in the array.
function addDates() {
var date = new Date(); // yor form date
var hodiday = ["08/09/2017","08/15/2017"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if(days > 0 ){
while (counter < days) {
date.setDate(date.getDate() + 1 );
var check = date.getDay();
var holidayCheck = hodiday.indexOf(Utilities.formatDate(date, "GMT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}

Advancing numeric string in localstorage

Working on a little task tracker applet that uses localstorage to both store tasks and keep a running tab of how many tasks have been created to date. The later is my issue.
Here's what I'm running, the issue is contained to variables "taskTracker" and "advanceTask".
function saveTask() {
var task = $("#task").val();
var taskDate = $("#taskDate").val();
if (newUser == null) {
var taskNumber = 0;
localStorage.setItem("taskTracker", "0");
localStorage.setItem("newUser", "no");
}
else {
var taskNumber = localStorage.getItem("taskTracker");
}
var advanceTask = taskNumber + 1;
localStorage.setItem('task' + taskNumber, task);
localStorage.setItem('task' + taskNumber + 'date', taskDate);
localStorage.setItem("taskTracker", advanceTask);
console.log(advanceTask);
displayTasks();
}
If you take a look at the "advanceTask" variable, my intention is to advance the numerical value stored in "taskTracker" each time this function is invoked. However, all I'm getting is an additional "1" appended to the value each time.
Thoughts? <3
There is a difference between string + number and number + number. Your current solution is like the stringPlusOne function below. You need to convert the string to a number (using parseInt is one way) and then do the math, like the stringPlusOne2 function below
function stringPlusOne(str) {
console.log(str + 1);
}
function stringPlusOne2(str) {
console.log(parseInt(str, 10) + 1);
}
stringPlusOne("2");
stringPlusOne2("2");

internet explorer match() not working correctly

I have a really weird error on IE.
I am using knockout custom validations. And one of my custom validations is to validate date.
function:
function isValidDate(txtDate) {
var currVal = txtDate;
if (currVal == '' || currVal == null)
return false;
//Declare Regex
var rxDatePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
var dtArray = currVal.match(rxDatePattern); // is format OK?
if (dtArray == null)
return false;
/*continue of logic*/
}
This works great, when I run it first time. But then I do a redirect to server and return to the same page.
And the validation is called again at that point the problem begins.
I have a two snapshots of memory. They look identical to me. But there has to be some difference that I don't see or the match method is somehow broken.
The difference is not the dtArray == null that is the problem. You can try to run it in console. And it parse the dtArray correctly....
Both snapshot are on the same line ( if (dtArray == null) )
beforeRedirect:
afterRedirect:
Update. I solved my problem.
problem was that I was setting my observable property something like this:
var date = "1990-01-01T00:00:00";
var dob = new Date(date).toLocaleDateString();
masterModel.Dob(dob);
when I do it like this the match works fine now:
var date = "1990-01-01T00:00:00"
var dob = new Date(date);
var dobstring = dob.getDate() + "/" + (dob.getMonth()+1) + "/" + dob.getFullYear();
masterModel.Dob(dobstring);
if you want to see the difference run this on IE in console. My IE version is 11.0.9600
//because I am in UK my locale string is dd/MM/yyyy if you get different one this problem won't work for you!
var date = "1990-01-01T00:00:00"
var dob = new Date(date).toLocaleDateString();
var rxDatePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
console.log(dob);
console.log(dob.match(rxDatePattern));
//vs
var date = "1990-01-01T00:00:00"
var dob = new Date(date);
var dobstring = dob.getDate() + "/" + (dob.getMonth()+1) + "/" + dob.getFullYear();
var rxDatePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
console.log(dobstring);
console.log(dobstring.match(rxDatePattern));
Try simply checking for falsy values. The empty string, null and undefined are all falsy, there is no need to be more specific than that here.
function isValidDate(txtDate) {
if (!txtDate) return false;
var rxDatePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
var dtArray = currVal.match(rxDatePattern);
if (!dtArray) return false;
/*continue of logic*/
}
That being said, I strongly suggest you use a date library (most prominently: moment.js) to do any date parsing, -calculation and -validation work. Don't roll your own regex when a fully functional and properly tested library has been written.
To think one step further, with knockout it's much easier to store an actual date object in an observable, so there is no need to parse any date strings at all, ever. You can also format it for display on screen any way you like, instead of limiting yourself/the user to a single format.
This way you would not need to do any date format validation at all. Either the observable contains a date - or not. For best effect use that together with a date picker widget (for example the one from knockout-jqueryui).
View model:
this.exampleDate = ko.observable();
View, assuming jQueryUI + knockout-jqueryui:
<input type="text" data-bind="datepicker: {
dateFormat: 'dd.mm.yyyy'
}, value: exampleDate" />

Query Instagram posts by hashtag and time range

I'm trying to query posts from Instagram by providing the hashtag and the time range (since and until dates).
I use the recent tags endpoint.
https://api.instagram.com/v1/tags/{tag-name}/media/recent?access_token=ACCESS-TOKEN
My code is written in Node.js using the instagram-node library (see the inline comments):
// Require the config file
var config = require('../config.js');
// Require and intialize the instagram instance
var ig = require('instagram-node').instagram();
// Set the access token
ig.use({ access_token: config.instagram.access_token });
// We export this function for public use
// hashtag: the hashtag to search for
// minDate: the since date
// maxDate: the until date
// callback: the callback function (err, posts)
module.exports = function (hashtag, minDate, maxDate, callback) {
// Create the posts array (will be concated with new posts from pagination responses)
var posts = [];
// Convert the date objects into timestamps (seconds)
var sinceTime = Math.floor(minDate.getTime() / 1000);
var untilTime = Math.floor(maxDate.getTime() / 1000);
// Fetch the IG posts page by page
ig.tag_media_recent(hashtag, { count: 50 }, function fetchPosts(err, medias, pagination, remaining, limit) {
// Handle error
if (err) {
return callback(err);
}
// Manually filter by time
var filteredByTime = medias.filter(function (currentPost) {
// Convert the created_time string into number (seconds timestamp)
var createdTime = +currentPost.created_time;
// Check if it's after since date and before until date
return createdTime >= sinceTime && createdTime <= untilTime;
});
// Get the last post on this page
var lastPost = medias[medias.length - 1] || {};
// ...and its timestamp
var lastPostTimeStamp = +(lastPost.created_time || -1);
// ...and its timestamp date object
var lastPostDate = new Date(lastPostTimeStamp * 1000);
// Concat the new [filtered] posts to the big array
posts = posts.concat(filteredByTime);
// Show some output
console.log('found ' + filteredByTime.length + ' new items total: ' + posts.length, lastPostDate);
// Check if the last post is BEFORE until date and there are no new posts in the provided range
if (filteredByTime.length === 0 && lastPostTimeStamp <= untilTime) {
// ...if so, we can callback!
return callback(null, posts);
}
// Navigate to the next page
pagination.next(fetchPosts);
});
};
This will start fetching the posts with the most recent to least recent ones, and manually filter the created_time.
This works, but it's very very inefficient because if we want, for example, to get the posts from one year ago, we have to iterate the pages until that time, and this will use a lot of requests (probably more than 5k / hour which is the rate limit).
Is there a better way to make this query? How to get the Instagram posts by providing the hashtag and the time range?
I think this is the basic idea you're looking for. I'm not overly familiar with Node.js, so this is all in plain javascript. You'll have to modify it to suit your needs and probably make a function out of it.
The idea is to convert an instagram id (1116307519311125603 in this example) to a date and visa versa to enable you to quickly grab a specific point in time rather then backtrack through all results until finding your desired timestamp. The portion of the id after the underscore '_' should be trimmed off as that refers, in some way, to the user IIRC. There are 4 functions in the example that I hope will help you out.
Happy hacking!
//static
var epoch_hour = 3600,
epoch_day = 86400,
epoch_month = 2592000,
epoch_year = 31557600;
//you'll need to set this part up/integrate it with your code
var dataId = 1116307519311125603,
range = 2 * epoch_hour,
count = 1,
tagName = 'cars',
access = prompt('Enter access token:'),
baseUrl = 'https://api.instagram.com/v1/tags/' +
tagName + '/media/recent?access_token=' + access;
//date && id utilities
function idToEpoch(n){
return Math.round((n / 1000000000000 + 11024476.5839159095) / 0.008388608);
}
function epochToId(n){
return Math.round((n * 0.008388608 - 11024476.5839159095) * 1000000000000);
}
function newDateFromEpoch(n){
var d = new Date(0);
d.setUTCSeconds(n);
return d;
}
function dateToEpoch(d){
return (d.getTime()-d.getMilliseconds())/1000;
}
//start with your id and range; do the figuring
var epoch_time = idToEpoch(dataId),
minumumId = epochToId(epoch_time),
maximumId = epochToId(epoch_time + range),
minDate = newDateFromEpoch(epoch_time),
maxDate = newDateFromEpoch(epoch_time + range);
var newUrl = baseUrl +
'&count=' + count +
'&min_tag_id=' + minumumId +
'&max_tag_id=' + maximumId;
//used for testing
/*alert('Start: ' + minDate + ' (' + epoch_time +
')\nEnd: ' + maxDate + ' (' + (epoch_time +
range) + ')');
window.location = newUrl;*/
To support this excellent answer, an instagram ID is generated via the plpgSQL function:
CREATE OR REPLACE FUNCTION insta5.next_id(OUT result bigint) AS $$
DECLARE
our_epoch bigint := 1314220021721;
seq_id bigint;
now_millis bigint;
shard_id int := 5;
BEGIN
SELECT nextval('insta5.table_id_seq') %% 1024 INTO seq_id;
SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
result := (now_millis - our_epoch) << 23;
result := result | (shard_id << 10);
result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;
from Instagram's blog
Despite a similar getting posts process, Data365.co Instagram API, I currently working at, seems to be more suitable and efficient. It does not have a limit of 5,000 posts per hour, and you can specify the period of time for which your need posts in the request itself. Also, the billing will be taken into account only posts from the indicated period. You won't have to pay for data you don't need.
You can see below a task example to download posts by the hashtag bitcoins for the period from January 1, 2021, to January 10, 2021.
POST request: https://api.data365.co/v1.1/instagram/tag/bitcoins/update?max_posts_count=1000&from_date=2021-01-01&to_date=2021-01-10&access_token=TOKEN
A GET request example to get the corresponding list of posts:
https://api.data365.co/v1.1/instagram/tag/bitcoins/posts?from_date=2021-01-01&to_date=2021-01-10&max_page_size=100&order_by=date_desc&access_token=TOKEN
More detailed info view in API documentation at https://api.data365.co/v1.1/instagram/docs#tag/Instagram-hashtag-search

Javascript to open file and read something using regular expressions

I would like to make a small gadget to use at work and show me the time of check in, from the morning.
I am trying to open a network file using http protocol and read from it the line which is referring to my check in.
This is located on our intranet and can be accessed like this:
filename = 'http://www.intranet.loc/docs/dru/Acces/' + ystr + '-' + mstr + '-' + dstr + '.mvm';
Every employer has a unique code for check in. The structure of the check In file is like this:
12:475663:1306285:072819:11:1:1:0:
12:512362:1306285:072837:11:1:1:0:
12:392058:1306285:072927:11:1:1:0:
12:516990:1306285:072947:11:1:1:0:
12:288789:1306285:073018:11:1:1:0:
12:510353:1306285:073032:11:1:1:0:
12:453338:1306285:073033:11:1:1:0:
12:510364:1306285:073153:11:1:1:0:
12:510640:1306285:073156:11:1:1:0:
In this example, 12 is the gate number, which I don't need, the second is my ID, the third is the current date, and what I need is the fourth (the hour).
Edit:
I am using this function to return the content of the mvm file with no luck:
function readfile(fileToRead) {
var allText = [];
var allTextLines = [];
var Lines = [];
var Cells = [];
var txtFile = new XMLHttpRequest();
txtFile.open("GET",fileToRead, true);
allText = txtFile.responseText;
allTextLines = allText.split(/r\r\n|\n/);
return allTextLines;
}
Do you really need a RegEx? Would it be possible to split the line by ":"?
$.get('http://www.intranet.loc/docs/dru/Acces/' + ystr + '-' + mstr + '-' + dstr + '.mvm', function(data) {
var lines = data.split("\n"),
values;
for (var i in lines) {
values = lines[i].split(':');
}
});
With this you would have everything you need.

Categories

Resources