JSON.parse not working in PhoneGap - javascript

I'm working on a program that needs to save user data in a file as a JSON format. It is doing fine saving my data as JSON but when I try to use JSON.parse to parse my stored JSON it doesn't work.
Here is my code for storing the data:
function writeUser(data) {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs){
fs.root.getFile('user.data', {create: true, exclusive: false}, function(fe){
fe.createWriter(function(writer){
//Its converts my data to JSON here
writer.write(JSON.stringify(data));
//It displays this so I knows its been written!
console.log('File written');
}, failwrite);
}, failwrite);
}, failwrite);
}
function failwrite(error) {
console.log(error.code);
}
And here is the code that read my data:
function readUser(){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs){
fs.root.getFile('user.data', null, function(fe){
fe.file(function(file){
return readAsText(file);
}, failread);
}, failread);
}, failread);
}
function readAsText(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log(evt.target.result);
};
return reader.readAsText(file);
}
Its returns my data fine as a string, Here is what I get as a string {"status":"true","id":"1","password":"xx"}, But when I use JSON.parse with my data it returns unidentified object. Here is the part where it uses JSON.parse:
readUser();
var user = JSON.parse(readUser());
console.log(user);
It won't even run my console.log command with the parsed JSON.

the readUser does not return anything. the content of the file is available in the readAsText callback. you have to json parse the evt.target.result and continue from there.

For reading use:
jsonVariable = jQuery.parseJSON(evt.target.result);
For writing use:
writer.write(JSON.stringify(propFileJson));

Related

String to array of JSON object

I try to send data to my NodeJS server using HTTP protocol (vue-resource). I want to send a array of JSON object like this : [{"name":"Charlotte","surname":"Chacha","birth":"2000-04-02"},{"name":"Michael","surname":"Mic","birth":"1999-01-30"}].
My front code :
window.onload = function () {
var gamme = new Vue({
el:'#gamme',
data: {
myListe: []
},
methods: {
sendListe: function() {
this.$http.get("/NewListe?liste="+this.myListe).then(response=> {
if (response.body) {
console.log(response.body);
}
});
}
}
})
}
And my back code :
server.app.get("/NewListe", function(req, res) {
try {
let liste= req.query.liste;
console.log(liste);
} catch (e) {
console.log(e);
}
})
When I try to display the variable liste in the server side console, I obtain this : [object Object] . liste is a string type that I can't use. I would like to have an array of JSON, like in front.
I tried to parse like this JSON.parse(operationsGamme) , but I have this error : SyntaxError: Unexpected token o in JSON at position 1
You should surely be using a POST method if you are sending JSON data to the server - a GET just isn't designed for that sort of usage.
Since you have passed a JSON in the url, it will be URLEncoded. So, in the backend before you do JSON.parse(liste), you should do decodeURI(liste). decodeURI() will return the JSON string which you can parse and use it in your code. I hope this will fix your problem.

Firefox WebExtensions, get local files content by path

I'm trying to write a small add-on for firefox using the WebExtensions structure.
This add-on should read a local file content by it's absolute path:
"/home/saba/desktop/test.txt"
manifest.json
{
"manifest_version": 2,
"name": "Test - load files",
"version": "0.0.1",
"description": "Test - load files",
"permissions": [ "<all_urls>" ],
"background": {
"scripts": [ "main.js" ]
}
}
Here what I tried so far (inside the main.js):
Using XMLHttpRequest
function readFileAjax(_path){
var xhr = new XMLHttpRequest();
xhr.onloadend = function(event) {
console.log("onloadend", this);
};
xhr.overrideMimeType("text/plain");
xhr.open("GET", "file:///"+_path);
xhr.send();
}
readFileAjax("/home/saba/desktop/test.txt");
Failed.
I can't figure out why it always return an empty response
(test.txt contains "test", the path is correct)
onloadend XMLHttpRequest {
onreadystatechange: null,
readyState: 4,
timeout: 0,
withCredentials: false,
upload: XMLHttpRequestUpload,
responseURL: "",
status: 0,
statusText: "",
responseType: "",
response: ""
}
Using FileReader
function readFileFR(_path){
var reader = new FileReader();
reader.addEventListener("loadend", function() {
console.log("loadend", this.result)
});
reader.readAsText(file); // file ????
}
readFileFR("/home/saba/desktop/test.txt");
but here I got stuck because of the file argument.
This method usually get along with an input type="file" tag which gives back a .files array. (but I only have a local path string)
I searched if was possible to create a new Blob or File var using an absolute local file path but seams like it's not possible.
Using WebExtensions API
I didn't find any clue form the documentation pages on how to do this.
Isn't there (maybe) some kind of WebExtensions API which makes this possible like in the SDK?
https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/io_file
https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/io_text-streams
What am I doing wrong or missing?
..is it possible to get the content of a local file by it's absolute path with a WE Add-on?
I finally found the way to do this using the Fetch requests and FileReader APIs.
Here what I came up to:
function readFile(_path, _cb){
fetch(_path, {mode:'same-origin'}) // <-- important
.then(function(_res) {
return _res.blob();
})
.then(function(_blob) {
var reader = new FileReader();
reader.addEventListener("loadend", function() {
_cb(this.result);
});
reader.readAsText(_blob);
});
};
Using the example in my question this is how to use it:
readFile('file:///home/saba/desktop/test.txt', function(_res){
console.log(_res); // <-- result (file content)
});
ES6 with promises
If you prefer to use Promises rather than callbacks:
let readFile = (_path) => {
return new Promise((resolve, reject) => {
fetch(_path, {mode:'same-origin'})
.then(function(_res) {
return _res.blob();
})
.then(function(_blob) {
var reader = new FileReader();
reader.addEventListener("loadend", function() {
resolve(this.result);
});
reader.readAsText(_blob);
})
.catch(error => {
reject(error);
});
});
};
Using it:
readFile('file:///home/saba/desktop/test.txt')
.then(_res => {
console.log(_res); // <-- result (file content)
})
.catch(_error => {
console.log(_error );
});
This doesn't work, or at least not any longer taking the accepted answer into consideration.
Addon's run in a fake root meaning you can only ever access files which have been
Shipped with your extension [1] using e.g. fetch() or
Opened interactive (meaning initiated by the user using either the file
picker or drag&drop) through the File() constructor [2]
Everything else will lead to a Security Error: Content at moz-extension://... may not load data from file:///... causing fetch() to throw the aforementioned TypeError: NetworkError when attempting to fetch resource.
[1] https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources
[2] https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_files#open_files_in_an_extension_using_a_file_picker

S3: Grant access to xml list by access key + javascript

I have a javascript code that gets the xml list http://BUCKETNAME.s3.REGION.amazonaws.com/ of s3 bucket and uses it as a playlist:
AWS.config=
{ "accessKeyId": "ACCESS KEY",
"secretAccessKey": "SECRET KEY",
"region": "REGION" };
// Create S3 service object
s3 = new AWS.S3();
var params = {
Bucket: 'BUCKET NAME', /* required */
Delimiter: '',
EncodingType: 'url',
Marker: '',
MaxKeys: 0,
Prefix: '',
RequestPayer: 'requester'
};
s3.listObjects(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else
{
console.log('the list is approved '); // successful response
// Here is the function that convert the file list in the xml to an array
var b = document.documentElement;
b.setAttribute('data-useragent', navigator.userAgent);
b.setAttribute('data-platform', navigator.platform);
var radioName;
var radioTitle;
var tracklength= 0;
// setupPlayer function
function setupPlayer(href,name){
radioName= href;
radioTitle= name;
$.ajax({
type: "GET",
url: "http://BUCKETNAME.s3.REGION.amazonaws.com/?prefix=radio/"+radioName+"/",
dataType: "xml",
success: function(xml){
//tracklength=0;
tracks =[];
$(xml).find('Contents').each(function(){
tracklength=tracklength+1;
tracks.push({
"track": tracklength,
"file" : $(this).find('Key').text()
});
});
radio(tracks);
},
error: function() {
alert("An error occurred while processing XML file.");
}
});
}
}
As you can see, in this code I am taking the XML file and add a radio name (which is the folder name) , after that the ajax will save all the file names in this folder to an array tracks.
This code works perfectly if there is a list grantee permission for Everyone. So there is no need for aws config here. I can run the code inside else statement in listObjects function and it will give me the same response.
What I do want is to give the grant access to this key only, to make this function not work without the access key and secret key.
So no one can access the xml list except those who have the access and secret keys.
Is that possible ?
(This is not the full code, but you got the Idea, accessing the XML file of the bucket and getting the keys an saving them to an array).
You should use s3.getObject (http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property) to get your xml files instead of $.ajax call.

Chrome Apps : How to save blob content to fileSystem in the background?

In Chrome Apps, I'm downloading a blob content from a server using JavaScript XHR (Angular $http GET in particular, with response type 'blob')
How should I save this to chrome application's file system?
Currently using an Angular wrapper on HTML5 filesystem API
https://github.com/maciel310/angular-filesystem
I do not want to show user a popup (hence I can't use chrome.fileSystem. chooseEntry )
The chrome.fileSystem.requestFileSystem API is only supported by Kiosk-only apps.
Hence I'm using HTML5 FileSystem API instead of chrome's.
I'm using following code to make XHR to fetch blob.
$http({
url: SERVER_URL+"/someVideo.mp4",
method: "GET",
responseType: "blob"
}).then(function(response) {
console.log(response);
fileSystem.writeBlob(response.name, response).then(function() {
console.log("file saved");
}, function(err) {
console.log(err);
});
}, function (response) {
});
This is my writeBlob method
writeBlob: function(fileName, blob, append) {
append = (typeof append == 'undefined' ? false : append);
var def = $q.defer();
fsDefer.promise.then(function(fs) {
fs.root.getFile(fileName, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
if(append) {
fileWriter.seek(fileWriter.length);
}
var truncated = false;
fileWriter.onwriteend = function(e) {
//truncate all data after current position
if (!truncated) {
truncated = true;
this.truncate(this.position);
return;
}
safeResolve(def, "");
};
fileWriter.onerror = function(e) {
safeReject(def, {text: 'Write failed', obj: e});
};
fileWriter.write(blob);
}, function(e) {
safeReject(def, {text: "Error creating file", obj: e});
});
}, function(e) {
safeReject(def, {text: "Error getting file", obj: e});
});
}, function(err) {
def.reject(err);
});
return def.promise;
},
This shows SECURITY_ERR as It was determined that certain files are unsafe for access within a Web application, or that too many calls are being made on file resources.
What's the solution for this?
I've tried using --allow-file-access-from-files flag while launching app. It doesn't help.
Chrome Application's sandbox storage doesn't allow files to be stored in root directory (i.e. / )
Modify the code to save it in a specific sub-directory under it.
For example -
fileSystem.writeBlob("/new"+response.name, response).then(function() {
console.log("file saved");
}, function(err) {
console.log(err);
});
This would successfully save the file under /new/ directory.
To expand on this, here is a full example app on how to download a file and save the blob and display it back to the user.
https://github.com/PierBover/chrome-os-app-download-example

Uploading Avatar on Parse (using AngularParse Service)

{"name":"tfss-4dde4ec8-e678-495a-a5d0-d3e51f0bdafc-search-pic-img6.jpg","url":"http://files.parsetfss.com/d130ccda-cf9f-4264-999e-09305bed0fd1/tfss-4dde4ec8-e678-495a-a5d0-d3e51f0bdafc-search-pic-img6.jpg"}
This is the return Object, When I upload the file on the parse server. I want to use this object to store it on the Parse Class avatar column as type "file" not string. In short I am trying to store it as image file after uploading. I want to do it in Cloud Code javascript rather than on html javacript. I want to send the object to parse and store it as image file.
Here's my cloud code. I am new to parse a bit.
Parse.Cloud.beforeSave("editProfileweb", function(request) {
var avatar = request.object;
var user = request.user;
if (user) {
user.set("avatar",avatar);
user.save(null, {
success: function(user) {
response.success();
},
error: function(error) {
// Show the error message somewhere and let the user try again.
response.success();
}
});
} else {
response.error("User not authenticated");
} });
I guess this is what you are looking for
Object.set({columnName: {"name": File.name, "url": File.url, "__type": "File"}});

Categories

Resources