Checking a directory for a file in phonegap - javascript

Hey 2 questions within this post, they are probably simple for you experienced js guys :-)
First; why is "filename" undefined inside the readEntries when I pass it along?
Second; Why is it always true, when the directory is empty?
Heres my code: I'm calling getPicturepath with a string like "women.png".
function getPicturePath(filename){
alert(filename); //is correct
var reader = DATADIR.createReader();
reader.readEntries(function(entries, filename){
alert(filename);//is undefined ???
var doWeHaveIt = function(entries,filename){
checkForFile(entries,filename)
};
if(doWeHaveIt){
alert('allready have: '+DATADIR.fullPath+filename);
} else {
alert('need to download file: '+filename);
}
},onError);
}
function checkForFile(entries,filename){
console.log("The dir has "+entries.length+" entries.");
if(entries.indexOf(filename)!=-1){
alert(filename+' allready exists');
return true;
} else {
alert(filename+" doesn't exists");
return false;
}
}

reader.readEntries(function(entries, filename){
This is the function defining the parameters entries and filename.
For example, this function might do something like:
readEntries: function( callback ) {
// do something, then
callback( some, datas );
}
If you just want to use filename in this function, just use it. Like this:
function getPicturePath(filename){
alert(filename); //is correct
var reader = DATADIR.createReader();
reader.readEntries(function(entries){
alert(filename);// is still correct
The second part (always true) is because of this:
function hi() {}
if ( hi ) {
// You're always getting there.
}
What I wrote is exactly what you did. I let you guess how to correct that :-)

Related

Console.log not working when testing regex

Can someone explain why my console log is not working?
Every time I select the file for verification to see if anything shows in the console nothing happens
document.addEventListener("DOMContentLoaded", function() {
document.getElementById('file').onchange = function() {
var extPermitidas = ['txt'];
var extArquivo = this.value.split('.').pop();
if (typeof extPermitidas.find(function(ext) {
return extArquivo == ext;
}) == 'undefined') {
alert('The file cannot be used because its extension is not allowed!');
return;
} else {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(progressEvent) {
// By lines
var lines = this.result.split('\n');
let N = /^(N1\d{14}.{78}|N9\d{14}.{14}\d{6})$/;
for (var line = 0; line < lines.length; line++) {
if (N.test(lines[line]) == N) {
console.log("valid file");
} else {
console.log("invalid file");
}
}
};
reader.readAsText(file);
}
alert('file successfully validated!');
}
});
<input type="file" id="file" />
EDIT
Could it be a problem in the conditional if (N.test(lines[line]) == N)?
This appears to be a function context issue. Try changing var file = this.files[0]; to var file = document.getElementById("file").files[0];.
this can sometimes be tricky since its value is determined by how a function is called (runtime binding). See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
Edit:
The conditional if (N.test(lines[line]) == N) is strange. The test() method executes a search for a match between a regular expression and a specified string and returns true or false. So, you don't need to compare the return of test to == N. Plus, you almost always want to use triple equals (===).
Have you already check your conditions or try to place the console.log in various parts of your code? Maybe it's an issue with event firing. I've tried to run you regex with my console I guess it works smoothly.
regex result

Adding [0] causes callback to be called twice?

I'm writing utility for some minecraft stuff, whatever... So, first of all I have a code that can extract specified files from archive and give there content in callback:
const unzip = require("unzip-stream");
const Volume = require("memfs").Volume;
const mfs = new Volume();
const fs = require("fs");
function getFile(archive, path, cb) {
let called = false;
fs.createReadStream(archive)
.pipe(unzip.Parse())
.on("entry", function(entity) {
if (path.includes(entity.path)) {
entity.pipe(mfs.createWriteStream("/" + path))
.on("close", function() {
mfs.readFile("/" + path, function(err, content) {
if (!called) cb(content);
called = true;
mfs.reset();
});
}).on("err", () => {});
} else {
entity.autodrain();
}
});
}
module.exports = { getFile };
It works perfect when I test it in interactive console:
require("./zip").getFile("minecraft-mod.jar", ["mcmod.info", "cccmod.info"], console.log); // <= Works fine! Calls callback ONCE!
When I started to develop utility using this code I discovered a VERY strange thing.
So I have filenames in files array.
I'm using async/eachSeries to iterate over it. I have no callback function - only iterate one.
I have this code to parse .json files in mods:
let modinfo = Object.create(JSON.parse(content.replace(/(\r\n|\n|\r)/gm,"")));
It also works fine. But here comes magic...
So, .json files can contain array or object. If it's array we need to take first element of it:
if (modinfo[0]) modinfo = modinfo[0];
It works.
But, if it's object we need to take first element of modlist property in in:
else modinfo = modinfo.modlist[0];
And if modinfo was and object boom - callback now fires TWICE! WHAT?
But, if I remove [0] from else condition:
else modinfo = moninfo.modlist; // <= No [0]
Callback will be called ONCE! ???
If I try to do something like this:
if (modinfo[0]) modinfo = modinfo[0];
else {
const x = modinfo.modlist;
modinfo = x[0];
}
Same thing happens...
Also, it's called without arguments.
I tried to investigate - where callback is called twice. Read the zip extractor code again... It has those lines:
This:
let called = false;
And those:
if (!called) cb(content);
called = true;
So, if for some reason even this condition fires up two times:
if (path.includes(entity.path)) {
It should not call callback, right? No! Not only that, but if I try to
console.log(called);
It will log false two times!
NodeJS version: v8.0.0
Full code:
function startSignCheck() {
clear();
const files = fs.readdirSync("../mods");
async.eachSeries(files, function(file, cb) {
console.log("[>]", file);
zip.getFile("../mods/" + file, ["mcmod.info", "cccmod.info"], function(content) {
console.log(content);
console.log(Buffer.isBuffer(content));
if (content != undefined) content = content.toString();
if (!content) return cb();
let modinfo = Object.create(JSON.parse(content.replace(/(\r\n|\n|\r)/gm, "")));
if (modinfo[0]) modinfo = modinfo[0];
else modinfo = modinfo.modlist[0];
//if (!modinfo.name) return cb();
/*curse.searchMod(modinfo.name, modinfo.version, curse.versions[modinfo.mcversion], function(link) {
if (!link) return cb();
signature.generateMD5("../mods/" + file, function(localSignature) {
signature.URLgenerateMD5(link, function(curseSignature) {
if (localSignature === curseSignature) {
console.log(file, "- Подпись верна".green);
} else {
console.log(file.bgWhite.red + " - Подпись неверна".bgWhite.red);
}
cb();
});
});
});*/
});
});
}
Example contents of mcmod.info is:
{
"modListVersion": 2,
"modList": [{
"modid": "journeymap",
"name": "JourneyMap",
"description": "JourneyMap Unlimited Edition: Real-time map in-game or in a web browser as you explore.",
"version": "1.7.10-5.1.4p2",
"mcversion": "1.7.10",
"url": "http://journeymap.info",
"updateUrl": "",
"authorList": ["techbrew", "mysticdrew"],
"logoFile": "assets/journeymap/web/img/ico/journeymap144.png",
"screenshots": [],
"dependants":[],
"dependencies": ["Forge#[10.13.4.1558,)"],
"requiredMods": ["Forge#[10.13.4.1558,)"],
"useDependencyInformation": true
}]
}
Problem was that I was using modlist instead of modList. Not it works! Thanks for solution, Barmar

Put data from a IndexedDB data base in a variable

I'm trying to put the data read from the database in a variable. I have tryed many things, including a callback function, but nothing looks to work when the process is outside of the "opencursor().onsuccess" function scope.
The "Alert 1" show the result correctly, but "Alert 2" and "Alert 3" don't.
I'm calling the 'main()' function from HTML code.
I'm really frustrated, because I have been mining internet searching for the solution without any positive result.
Can anybody help me, please?
Thanks a lot.
var data=[];
function kkeyget(t1, db_name, db_version)
{
var request = indexedDB.open(db_name, db_version);
request.onerror=function()
{
alert("Error");
}
request.onsuccess=function(event)
{
var db=this.result;
var trans = db.transaction(t1, "readonly");
var objectStore = trans.objectStore(t1);
objectStore.openCursor().onsuccess = function(event)
{
var cursor = event.target.result;
if (cursor)
{
data.push(cursor.value);
//Alert 1:
alert(data[0].id);
cursor.continue();
}
else alert("No more entries!");
};
}
//Alert 2:
alert(data[0].id);
}
function main()
{
kkeyget("agenda", "example_db", 1);
//Alert 3:
alert(data[0].id);
}
Correct. Because all indexedDB actions are asynchronous, your code will run:
alert 2 // undefined
alert 3 // undefined
alert 1 // correct
In order to get this closer to a synchronous action, you need to have it call a new function after it's done collecting data. Where your alert("No more entries!") is.
Instead of trying to return a key, pass in a custom callback function that takes the retrieved key as its argument.
// Your old function slightly modified
function kkeyget(t1, db_name, db_version, callback, fallback) {
// ... yada yada yada
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
callback(cursor.value);
} else {
fallback();
}
}
}
// Now in your calling code:
kkeyget('a','b',1, function(id) {
// Do something with the 'id'
// here in this anonymous function callback
}, function() {
// Do something here to indicate no match
});

use javascript to find parameter in url and then apply if then logic

I am trying to make my page perform an action only if it sees that a particular parameter is present in the url.
I essentially want the javascript code to do this:
consider an example page such as: http://www.example.com?track=yes
If a page loads that contains the parameter 'track' within the url, print 'track exists', else if the 'track' parameter doesn't exist print 'track does not exist'
This should work:
if (window.location.search.indexOf('track=yes') > -1) {
alert('track present');
} else {
alert('track not here');
}
Use something like the function from Artem's answer in this SO post:
if (getParameterByName('track') != '') {
alert ('run track');
}
It's not hard to split up the query string to find the relevant bits:
var path = location.substr(1), // remove ?
queryBits = path.split('&'),
parameters = {},
i;
for (i = 0 ; i < queryBits.length ; i++) {
(function() { // restrict keyval to a small scope, don't need it elsewhere
var keyval = queryBits[i].split('=');
parameters[decodeURIComponent(keyval[0])] = decodeURIComponent(keyval[1]);
}());
}
// parameters now holds all the parts of the URL as key-value pairs
if (parameters.track == 'yes') {
alert ('track exists');
} else {
alert ("it doesn't");
}
What you're looking for is called the Query String or Query Parameter. See this function to get it w/o the use of plugins like jQuery: How can I get query string values in JavaScript?
You can use the window.location.search property:
if(/(^|&)track(&|$)/.test(window.location.search.substring(1))) {
alert('track exists!');
} else {
alert('it doesn\'t...');
}

How to carry "getjson" functionality from one func to another?

Basically I have a getjson call to call for a bunch load of data. Now I am getting sick of the amount of if data is null else checks.
For Example:
if (data.Height == "") {
$('#DataHeight').html('No Data is Available');
}
else {
$('#DataHeight').html(data.Height);
}
Reason being is the user has to be alerted asap that data is not available.
So I went off and am trying to write a DataCheck.js to include and handle all this outside of my pretty little page :D.
Function:
function DataNullCheck(ObjectName) {
if (data.ObjectName == "") {
$('"#Data' + ObjectName + '"').html('No Datablurgh');
}
else {
$('"#Data' + ObjectName + '"').html(data.ObjectName);
}
}
and to call it inside my function
function getdata() {
$.ajaxSetup({
cache: false
});
$.getJSON(urldefault, function (data) {
DataNullCheck('Height');
.......
And Data is undefined. Because it is not within the JSON call?
Any help or hints towards the right direction would be appreciated especially an explanation of why it works one way or another. Thanks in advance.
How would I carry through the getJson call functionality to my little function?
Pass data as a parameter to your function:
function DataNullCheck(data, ObjectName) { // you can check for null any property of data
// e.g. DataNullcheck(data, "Width"), or
// DataNullCheck(data, "Height") etc.
if (!data[ObjectName]) {
$('"#Data' + ObjectName + '"').html('No Datablurgh');
}
else {
$('"#Data' + ObjectName + '"').html(data.ObjectName);
}
}

Categories

Resources