Require local image downloaded with react-native-fetch-blob - image

I’m trying to require an image downloaded with react-native-fetch-blob in my Image component, but when I give it the image path it keeps saying me « Unknow named module: ‘/Users/…/Library/…’
What is the right way to require images stored in a local directory ?
let imagePath = null
RNFetchBlob
.config({
fileCache : true
})
.fetch('GET', uri)
// the image is now dowloaded to device's storage
.then((resp) => {
// the image path you can use it directly with Image component
imagePath = resp.path()
this.setState({ uri: require(imagePath) })
try {
AsyncStorage.setItem(`${this.props.uri}`, imagePath);
} catch (error) {
console.log(error)
}
})
My render method :
render() {
return(
<Image style={this.props.style} source={this.state.uri} />
)
}
The problem is not because I set a variable as source because it's working when I put something like : this.setState({ uri: require('../images/test.jpg') }) after my download.

require(imagePath) exists to help packager to find local images and place them to application bundle.
When you need to show dynamically loaded image, you simple need to pass file location as URI, for ex:
render() {
const imageAbsolutePath = this.state.imagePath;
const imageUri = 'file://' + imageAbsolutePath;
return <Image source={{uri: imageUri}}/>;
}
So, you shold not need any require statements in this case.

Related

Display dynamic image in VueJs with Laravel

I am trying to display image stored in storage/app/public/images folder with VueJS but somehow the image is not displayed
in vue file
<img v-bind:src="img" />
export default {
data(){
return{
img:'',
};
},
mounted() {
axios.get('/api/image')
.then(res => {
this.img = res.data
})
.catch(error => console.log(error))
},
The path returned is correct, however the image is not shown.
Kindly help
Create a function to return the photo
<img class="profile-pic" :src="getProfilePhoto()" alt="profile-pic">
getProfilePhoto() { // return default if image is null
var photo = (this.img == null) ? "/images/user.jpg" : this.img
return photo
},
Here is a link
With a working example.

Configure screenshot folder in Cypress

I am using Cypress as my user interface test automation framework.
Currently my folder structure for spec file (logical organization of test files) is:
~/myAccount/header/header.spec.js
~/myAccount/footer/footer.spec.js
~/myAccount/mainTabs/home.spec.js
and so on...
Now when I configure my screenshot folder in cypress.json to screenshots and save screenshots of failed test cases, cypress internally creates a folder structure inside screenshots folder. For instance if a test fails in footer.spec.js, it saves the screenshot in
~/screenshots/myAccount/footer/footer.spec.js
I want to get rid of this recursive folder structure and save all screenshots inside screenshots folder (so that I can easily access these screenshots and add it to my mochawesome report).
Is there any way to do it ?
Any help will be appreciated and let me know if I was unable to put my question properly. I am willing to add more information.
Yes, you can use the Cypress screenshot API:
for example:
// cypress/plugins/index.js
const fs = require('fs')
module.exports = (on, config) => {
on('after:screenshot', (details) => {
// details will look something like this:
// {
// size: 10248
// takenAt: '2018-06-27T20:17:19.537Z'
// duration: 4071
// dimensions: { width: 1000, height: 660 }
// multipart: false
// pixelRatio: 1
// name: 'my-screenshot'
// specName: 'integration/my-spec.js'
// testFailure: true
// path: '/path/to/my-screenshot.png'
// scaled: true
// blackout: []
// }
// example of renaming the screenshot file
const newPath = '/new/path/to/screenshot.png'
return new Promise((resolve, reject) => {
fs.rename(details.path, newPath, (err) => {
if (err) return reject(err)
// because we renamed/moved the image, resolve with the new path
// so it is accurate in the test results
resolve({ path: newPath })
})
})
})
}
You could also create symlinks if you wanted the image in two places, for example.

Generated PDF does not have image included from its Handlebars template

app.get('/individual_report/:athlete_id', function(req, res) {
database.select('*').from('participants').then(data => {
if (data.length) {
res.render('individual_report', {
name: data
});
const hbsfile = fs.readFileSync(__dirname + '/../public/views/individual_report.hbs', 'utf8');
const document = {
template: hbsfile,
context: {
options: {
dataForPDF: data,
ssl_logo: '../public/static/assets/image/white_ssl_logo.png',
},
},
path: __dirname + '/../public/reports/' + data[0].first_name + " " + data[0].last_name + '\'s scores.pdf'
};
pdf.create(document, options).then(res => {
console.log(res)
}).catch(error => {
console.error(error)
});
} else {
res.json({
msg: 'Invalid athlete ID'
});
}
}).catch(err => res.sendStatus(400));
});
The above node express route renders a html page and also generates a PDF using the HandleBars .hbs template.
<img class="ssl_logo" src="{{{options.ssl_logo}}}" alt="logo.png" width="120" height="50" />
This is what I have in the .hbs file that should display the logo image file.
The image is not rendered in the browser and also in the PDF file. However, the alt attribute is rendered on the browser and in the PDF. I looked into the console log and I get this unknown at the source attribute:
img class="ssl_logo" src(unknown) alt="logo.png" width="120" height="50"
I am using the dynamic-html-pdf node package to generate this report and can anyone suggest me something that might make this works? Thank you.
just try to use file protocol
ssl_logo: 'file://' + __dirname + '/public/static/assets/image/white_ssl_logo.png',
it will work normally even the SVG images will be generated
Welp, I am going to answer my own post. For some reason this piece of code is not reading the local image file, so what I did was uploading the image to google drive, get the shareable link, google how to modify the shareable link because the link that is generated will not work in our code, and replace the image file address with the link.
Hope this will help those who is or will have this issue. (Ultimately you have to solve the problem yourself, haizzzz)

Nativescript imagepicker .getImage() is not a function error

I have been trying to implement the answer to this question but keep getting the error "selected.getImage is not a function".
I have tried multiple different code examples at this point and I'm stumped. It seems like this is a type error, but I'm not sure where I can correct this.
I am looking to select a single image and return the path to that image in order to upload to the server. I don't need to display it on the device, though that is an option I suppose. Seems easy enough, but apparently I'm missing something.
I'm using v. 6.0.1 or the imagepicker plugin. I'd quote the code, but at this point I am using the exact example provided by Shiva Prasad in the above question.
Adding code per Max Vollmer:
var context = imagepickerModule.create({
mode: "single" // allow choosing single image
});
context
.authorize()
.then(function () {
return context.present();
})
.then(function (selection) {
console.log("Selection done:");
setTimeout(() => {
selection.forEach(function (selected) {
selected.getImage().then((source) => {
console.log(selected.fileUri); // this is the uri you need
});
});
}, 1000);
}).catch(function (e) {
console.log(e);
});
I was facing the exact same error yesterday.
I use the fromAsset function directly on the "selected" because apparently with the new version of this plugin, "selected" is an Asset. So you got an imageSource and you can use the "saveToFile" function that will copy the Asset into a new location (get this location using fileSystemModule from TNS). Use the path of this new location for your UI, and the image will appear. You can also create a file object from this location fileSystemModule.File.fromPath(path);, I use for upload.
context
.authorize()
.then(function () {
return context.present();
})
.then(function (selection) {
selection.forEach(function (selected) {
let file;
if (selected._android) {
file = fileSystemModule.File.fromPath(selected._android);
//viewModel.uploadFile(file);
}else{
imageSourceModule.fromAsset(selected).then((imageSource) => {
const folder = fileSystemModule.knownFolders.documents().path;
const fileName = "Photo.png";
const path = fileSystemModule.path.join(folder, fileName);
const saved = imageSource.saveToFile(path, "png");
if (saved) {
console.log("Image saved successfully!");
file = fileSystemModule.File.fromPath(path);
//viewModel.uploadFile(file);
}else{
console.log("Error! - image couldnt save.");
}
});
}
});
}).catch(function (e) {
console.log(e);
// process error
});
Explanation
The uncommented snippet (//viewModel.uploadFile(file);), viewModel reference (will be different on your app) and the function: uploadFile for example is where you would pass the file to upload it or set it to the image.src etc
Make sure to declare imageSourceModule at the top.
const imageSourceModule = require("tns-core-modules/image-source");

Can't get meteor FileCollection package to work

I am (unfortunately) working on a Windows machine so I had to manually add the FileCollection package to my app, but when I run my app, I can access the file collection and file collection methods from the browser console. However, I can't seem to get the event listeners set up on an actual page. (FYI, I am using iron-router for my templating architecture.)
It seems like the code that needs to be called is just not coming in the right order, but I've experimented with where I place the code and nothing seems to make a difference.
The server side code:
// Create a file collection, and enable file upload and download using HTTP
Images = new fileCollection('images',
{ resumable: true, // Enable built-in resumable.js upload support
http: [
{ method: 'get',
path: '/:_id', // this will be at route "/gridfs/images/:_id"
lookup: function (params, query) { // uses express style url params
return { _id: params._id }; // a mongo query mapping url to myFiles
}
}
]
}
);
if (Meteor.isServer) {
// Only publish files owned by this userId, and ignore
// file chunks being used by Resumable.js for current uploads
Meteor.publish('myImages',
function () {
return Images.find({ 'metadata._Resumable': { $exists: false },
'metadata.owner': this.userId });
}
);
// Allow rules for security. Should look familiar!
// Without these, no file writes would be allowed
Images.allow({
remove: function (userId, file) {
// Only owners can delete
if (userId !== file.metadata.owner) {
return false;
} else {
return true;
}
},
// Client file document updates are all denied, implement Methods for that
// This rule secures the HTTP REST interfaces' PUT/POST
update: function (userId, file, fields) {
// Only owners can upload file data
if (userId !== file.metadata.owner) {
return false;
} else {
return true;
}
},
insert: function (userId, file) {
// Assign the proper owner when a file is created
file.metadata = file.metadata || {};
file.metadata.owner = userId;
return true;
}
});
}
The client side code (currently in main.js at the top level of the client dir):
if (Meteor.isClient) {
// This assigns a file upload drop zone to some DOM node
Images.resumable.assignDrop($(".fileDrop"));
// This assigns a browse action to a DOM node
Images.resumable.assignBrowse($(".fileBrowse"));
// When a file is added via drag and drop
Images.resumable.on('fileAdded', function(file) {
// Create a new file in the file collection to upload
Images.insert({
_id : file.uniqueIdentifier, // This is the ID resumable will use
filename : file.fileName,
contentType : file.file.type
}, function(err, _id) {// Callback to .insert
if (err) {throwError('Image upload failed');}
// Once the file exists on the server, start uploading
Images.resumable.upload();
});
});
Images.resumable.on('fileSuccess', function(file) {
var userId = Meteor.userId();
var url = '/gridfs/images/' + file._id;
Meteor.users.update(userId, {
$set : {
"profile.$.imageURL" : url
}
});
Session.set('uploading', false);
});
Images.resumable.on('fileProgress', function(file) {
Session.set('uploading', true);
});
}
I think the issue might be with using IronRouter. I'll assume you are using some layout.html via Iron router and inside it you've added your template for your file table to be shown. (I'm guessing your are following the sampleApp that came with fileCollection.). I had a problem when I did this and it had to do with where I had the code that attached the listeners. The problem is where you have the code "Images.resumable.assignDrop($(".fileDrop"));" in your client file. The way you have it now, that line of code is running before your template is rendered within the layout.html. So the code can not find the DOM element ".fileDrop". To fix this create a layout.js file and use the rendered method like this...
Template.layout.rendered = function(){
Images.resumable.assignDrop($(".fileDrop"));
}

Resources