Hi, I'm trying to integrate this into my Meteor/React app, but I'm not quite sure on how to actually get the contents of a file. I used the same example as presented in the Readme, except I defined an absolute storagePath.
import { Meteor } from 'meteor/meteor';
import { FilesCollection } from 'meteor/ostrio:files';
const Images = new FilesCollection({
debug: true,
collectionName: 'Images',
storagePath: "/home/XXX/XXX/testDir"
});
// To have sample image in DB we will upload it on server startup:
if (Meteor.isServer) {
Images.denyClient();
Images.collection.attachSchema(Images.schema);
Meteor.startup(function () {
if (!Images.find().count()) {
Images.load('https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/logo.png', {
fileName: 'logo.png',
meta: {}
});
}
});
Meteor.publish('files.images.all', function () {
return Images.find().cursor;
});
} else {
Meteor.subscribe('files.images.all');
}
export default Images;
1) On my client in React, I import Images but how am I supposed to get the actual file contents? I want to display the image but I can't use the path stored in the Images collection because Meteor parses the path through the public/ folder.
2) Similarly, if this is a text file or any other file, how do I get the contents of the file? Say if I want to get the contents of a text file and display it in a React component, how should this be done?
I couldn't find any instance in the documentation which illustrates how this should be done specifically.
I'm trying to be able to console.log the data first before actually using it in my component. I tried to use link() but I don't think this is the correct way of doing it as it throws some errors:
const Component = () => {
useEffect(() => {
console.log(Images.link())
}, [])
return <div />
}
Appreciate any help, thanks.
@ajaypillay you're looking for .link() method. Let me know if it helped you
@dr-dimitru I tried the following:
const Component = () => {
useEffect(() => {
const fileRef = Images.collection.findOne({})
console.log(Images.link(fileRef))
}, [])
return <div />
}
But I get this Uncaught errorClass:
errorType: "Match.Error"
message: "Match error: Expected object, got undefined"
path: ""
sanitizedError: errorClass
details: undefined
error: 400
errorType: "Meteor.Error"
isClientSafe: true
message: "Match failed [400]"
reason: "Match failed"
stack: "Error: Match failed [400]\n at errorClass.<anonymous> (http://XXX.XXX.XX.XX:3000/packages/check.js?hash=75a
details: undefined
error: 400
errorType: "Meteor.Error"
isClientSafe: true
message: "Match failed [400]"
reason: "Match failed"
stack: "Error: Match failed [400]\n at errorClass.<anonymous> (http://XXX.XXX.XX.XX:3000/packages/check.js?hash=75ac
Nevermind, I got it working. I was doing this in React when in actuality it needs to be done on the server side. I'm running a Meteor/Apollo/React stack and I made a simple Graphql resolver to fetch the links, and it all works now because it's being done on the server-side.
Thank you!
@ajaypillay I'm glad this issue was solved quickly. Are you using Meteor methods in your solution?
There's also a way to publish/subscribe it as any other Meteor collection and those functions would work on a Client. But to be honest methods work better than pub/sub, and I prefer methods to pub/sub on "normal" meteor Collections
Please support this project with:
@dr-dimitru
I'm not using any Meteor methods actually, as Apollo/Graphql gives an interface to handle all operations with the database. I defined a Graphql query schema in Files.graphql:
extend type Query {
getFiles: String
}
And I have a separate file for the actual FileCollection, in files.jsx:
import { FilesCollection } from 'meteor/ostrio:files'
const Files = new FilesCollection({
debug: true,
collectionName: 'Files',
storagePath: "/XXX/XXX/XXX/directory"
})
export default Files
And in resolvers.jsx I have:
import Files from "./files";
export default {
Query: {
getFiles(obj, args, context) {
return Files.collection.findOne({}).link(fileRef, 'original, 'http://XXX.XXX.XX.XX:3000/')
}
}
}
And then in my React component I just query the database for the needed data.
import React from "react"
import { gql, useQuery } from '@apollo/client'
const Component = () => {
const {data, loading, error} = useQuery(gql`
query getFiles {
getFiles: getFiles
}
`)
if (loading) return <div />
if (error) console.log(error)
console.log(data) // Data will contain the URL string returned by the query
return (
<div />
)
}
And then I can use data in my component. I've found working with Apollo/Graphql very convenient, and I've abstracted away all the database logic to Apollo. The only thing I'm really using Meteor for right now explicitly is for the accounts package, and other nice things like hot-reloading.
@ajaypillay good Graphql use case, thank you for sharing in details
Most helpful comment
Nevermind, I got it working. I was doing this in React when in actuality it needs to be done on the server side. I'm running a Meteor/Apollo/React stack and I made a simple Graphql resolver to fetch the links, and it all works now because it's being done on the server-side.
Thank you!