Im trying to do a file upload function to IPFS that returns the string of the url for where the file is located. But I cannot get it to return it. I have tried using var and window to declare the variable but it always returns undefined.Also defined the enlace outside of the function but still it always declare undefined. Its like its not updating the value outside of the function. As the console log after it does print the url. (and yes I know there is some trash code, I have been trying to debug the problem)
function upload() {
const reader = new FileReader();
reader.onloadend = function() {
const ipfs = window.IpfsApi('localhost', 5001) // Connect to IPFS
const buf = buffer.Buffer(reader.result) // Convert data into buffer
ipfs.files.add(buf, (err, result) => { // Upload buffer to IPFS
if(err) {
console.error(err)
return
}
window.enlace = `http://127.0.0.1:8080/ipfs/${result[0].hash}`
console.log(`Url --> ${enlace}`)
console.log(typeof enlace)
//document.getElementById("url").innerHTML= url
//document.getElementById("url").href= url
//document.getElementById("output").src = url
})
}
const photo = document.getElementById("photo");
reader.readAsArrayBuffer(photo.files[0]); // Read Provided File
return window.enlace;
}
I believe ipfs.add is asynchronous, which means return window.enlace executes before window.enlace is set inside of your callback funcion.
Related
I am working on a PWA project where I have created an IndexedDB and stored the images and videos in it. On the next reload of page, if image/video is available in IndexedDB, it should load it from there.
function fetchMedia(id) {
var transaction = db.transaction(["media"]);
var objectStore = transaction.objectStore("media");
var request = objectStore.get(id);
request.onerror = function(event) {
console.log("Unable to retrieve daa from database!");
return "";
};
request.onsuccess = function(event) {
var imgFile = request.result;
console.log(imgFile)
var imgURL = window.URL.createObjectURL(imgFile);
return imgURL;
};
}
It always returns undefined.
When I console.log the imgFile, it shows that it's there in the IndexedDB:
File in IndexedDB:
I have also tried this but no success yet:
var imgURL = window.URL.createObjectURL(new Blob(imgFile, {'type': 'application/octet-stream'}));
What's the correct approach to load the files from IndexedDB?
If your screenshot is accurate, then request.result is not an image, it's an object {id: '13388-7247-6247-62584', file: Blob, ...}. You didn't just store the image file, you wrapped it in an object. So what you're getting back out is an object.
Try imgFile = request.result.file; instead.
You cannot return inside the callback, you should wrap it in a promise.
I'm trying to manipulate a local CSV file with JavaScript. My purpose is to display datas from my CSV on my website, like we were using an external API in JSON format for example.
const csvLocalFile =
"http://XXX/.../file.csv";
const openFile = async () => {
const csv = await fetch(csvLocalFile).then();
let reader = new FileReader();
reader.onload = function () {
let text = reader.result;
filecontent = text.replace("", "");
};
reader.readAsText(csv.files[0]);
};
openFile();
Chrome display this error :
TypeError: Cannot read properties of undefined (reading '0')
When I delete "[0]" from "reader.readAsText(csv.files[0])", I have this message error :
TypeError: Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'.
A empty .then() isn't the problem, turns out it works fine without a fn. but you should remove it regardless.
The FileReader can't read Response objects, only File & Blobs...
You say that you try to read a local file, but yet you use fetch to get a remote file, so what is it that your really trying to do? it's unclear of how to help you...
a csv isn't valid json data, so you can't use .then((res) => res.JSON())
beside res.JSON() is wrong, it should be all lowercased... res.json()
The FileReader is considered legacy so you no longer need it... use await blob.text() instead
here are two examples of how to read 1 remote file using fetch
// Simulate getting a file from eg a file input or drag and drop
const file = new File(['id,name\n10,bob'], 'file.csv', { type: 'text/csv' })
// Simulate a remote location to get the csv from
const url = URL.createObjectURL(file)
const csvLocalFile = url // http://XXX/.../file.csv
const openFile = async () => {
const response = await fetch(csvLocalFile)
const text = await response.text()
console.log(text)
}
openFile()
...and another with a actual local file selected from a user input
const fileInput = document.querySelector('#fileInput')
fileInput.onchange = async () => {
const file = fileInput.files[0]
const text = await file.text()
console.log(text)
}
// ignore code below this line...
// Create a dummy file that we can use to change the file input with...
const dummyFile = new File(['id,name\n10,bob'], 'file.csv', { type: 'text/csv' })
// Used for creating a new FileList in a round-about way
const b = new ClipboardEvent('').clipboardData || new DataTransfer()
b.items.add(dummyFile)
// simulate picking a file
fileInput.files = b.files
fileInput.onchange()
<input type="file" id="fileInput">
This is what I am trying to achieve, implement the firebase's resize image extension, upload an image, then when the resize is completed, add that dowloadUrl's thumbs to a Cloud Firestore document. This question helps me, but still can not identify the thumbs and get the download URL, this is what am have been trying so far.
Note: I set my thumbnail to be at root/thumbs
const functions = require('firebase-functions');
const { Storage } = require('#google-cloud/storage');
const storage = new Storage();
exports.thumbsUrl = functions.storage.object().onFinalize(async object => {
const fileBucket = object.bucket;
const filePath = object.name;
const contentType = object.contentType;
if (fileBucket && filePath && contentType) {
console.log('Complete data');
if (!contentType.startsWith('thumbs/')) {
console.log('This is not a thumbnails');
return true;
}
console.log('This is a thumbnails');
} else {
console.log('Incomplete data');
return null;
}
});
Method 1 : Client Side
Don't change the access token when creating the thumbnail.
Edit the function from gcloud cloud function console
Go to the function code by clicking detailed usage stats
Then click on code
Edit the following lines
Redeploy the function again
// If the original image has a download token, add a
// new token to the image being resized #323
if (metadata.metadata.firebaseStorageDownloadTokens) {
// metadata.metadata.firebaseStorageDownloadTokens = uuidv4_1.uuid();
}
Fetch the uploaded image using getDownloadURLfunction
https://firebasestorage.googleapis.com/v0/b/<project_id>/o/<FolderName>%2F<Filename>.jpg?alt=media&token=xxxxxx-xxx-xxx-xxx-xxxxxxxxxxxxx
Because the access token will be similar
https://firebasestorage.googleapis.com/v0/b/<project_id>/o/<FolderName>%2Fthumbnails%2F<Filename>_300x300.jpg?alt=media&token=xxxxxx-xxx-xxx-xxx-xxxxxxxxxxxxx
Method 2: Server Side
Call this function after thumbnail is created
var storage = firebase.storage();
var pathReference = storage.ref('users/' + userId + '/avatar.jpg');
pathReference.getDownloadURL().then(function (url) {
$("#large-avatar").attr('src', url);
}).catch(function (error) {
// Handle any errors
});
you need to use filePath for checking the thumbs
if(filePath.startswith('thumbs/'){...}
contentType has the metadata of files like type of image and etc.
FilePath will have the full path.
I'm trying to load in a relative file address into a function previously used by a file reader. On the site, I had a button that would let you pick local files to be loaded into a graphics renderer. I want to use a url to access these files relatively instead, but I can't figure out how to bind them to a file object. I have been using this mozilla documentation to try and figure it out.
Here is the code that was used originally:
// function that takes file input and renders the image
function readFiles(){
// Deal with file input
if (window.File && window.FileReader && window.FileList && window.Blob) {
var file1 = document.getElementById('fileinput').files[0];
var file2 = document.getElementById('fileinput').files[1];
// Call the file analyzer
fileAnalyzer( file1, file2 );
} else {
alert('The File APIs are not fully supported by your browser.');
}
}
Here is the code that I want to update:
// load cube button
var loadcube = document.getElementById('loadcube');
loadcube.onclick = function(evt) {
var file1 = new File([], "Object files/cube3.coor" );
var file2 = new File([], "Object files/cube3.poly" );
fileAnalyzer( file1, file2);
}
You can use the Fetch API to asynchronously fetch the resources, convert them to a Blob, and then construct a File like this:
function fetchAsFile(path) {
return fetch(path).then(function (response) {
return response.blob()
}).then(function (blob) {
return new File([blob], path)
})
}
var loadcube = document.getElementById('loadcube')
loadcube.addEventlistener('click', function () {
var p1 = fetchAsFile('Object files/cube3.coor')
var p2 = fetchAsFile('Object files/cube3.poly')
Promise.all([p1, p2]).then(function (files) {
fileAnalyzer(files[0], files[1])
})
})
Using ES2017 async / await, you can simplify the above like this:
async function fetchAsFile(path) {
let response = await fetch(path)
let blob = await response.blob()
return new File([blob], path)
}
var loadcube = document.getElementById('loadcube')
loadcube.addEventlistener('click', async function () {
let p1 = fetchAsFile('Object files/cube3.coor')
let p2 = fetchAsFile('Object files/cube3.poly')
let files = await Promise.all([p1, p2])
fileAnalyzer(files[0], files[1])
})
I'm trying to create a csv from a string and upload it to my S3 bucket. I don't want to write a file. I want it all to be in memory.
I don't want to read from a file to get my stream. I would like to make a stream with out a file. I would like this method createReadStream, but instead of a file, I would like to pass a string with my stream's contents.
var AWS = require('aws-sdk'),
zlib = require('zlib'),
fs = require('fs');
s3Stream = require('s3-upload-stream')(new AWS.S3()),
// Set the client to be used for the upload.
AWS.config.loadFromPath('./config.json');
// Create the streams
var read = fs.createReadStream('/path/to/a/file');
var upload = s3Stream.upload({
"Bucket": "bucket-name",
"Key": "key-name"
});
// Handle errors.
upload.on('error', function (error) {
console.log(error);
});
upload.on('part', function (details) {
console.log(details);
});
upload.on('uploaded', function (details) {
console.log(details);
});
read.pipe(upload);
You can create a ReadableStream and push your string directly to it which, can then be consumed by your s3Stream instance.
const Readable = require('stream').Readable
let data = 'this is your data'
let read = new Readable()
read.push(data) // Push your data string
read.push(null) // Signal that you're done writing
// Create upload s3Stream instance and attach listeners go here
read.pipe(upload)