0

i have table 'case' that contains an image column, i want users to insert into the case table and be able to upload an image, on the home page users can view cases along with image of each case. so far i have tried:

 public function createcase(Request $request){

        $validator = Validator::make($request->all(), [
            'title' => 'required',
            'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            'description' => 'required',
            'caseTypeId' => 'required',
            'amountneeded' =>'required',
            'uid' => 'required',
            'visible' => 'required',
        ]);
        if ($validator->fails()) {
            return response()->json(['error'=>$validator->errors()], 401);
        }
      $image = $request->file('image');
      $path = $image->store('public');

        $case = casee::create([
            'title' => $request->title,
            'description' => $request->description,
            'caseTypeId' => $request->caseTypeId,
            'amountneeded' => $request->amountneeded,
            'uid' => $request->uid,
            'visible' => $request->visible,
            'image' => $path,
        ]);
        return response()->json(['image' => $image]);

to upload:

  <input type="file" id="image" @change="onFileChange" />

 methods: {
        onFileChange(e) {
      this.image = e.target.files[0];
    },
  async postcase() {
            const formData = new FormData();
            formData.append('title', this.title);
            formData.append('description', this.description);
            formData.append('amountneeded', this.amountneeded);
            formData.append('caseTypeId', this.selectedcasetype);
            formData.append('uid', this.uid);
            formData.append('visible', 1);
            formData.append('image', this.image);
           
            try {
                 await axios.post('http://127.0.0.1:8000/api/postcase', formData).then(response => {
          console.log(response.data);
        })
            
            } catch (error) {
                console.log(response.data);
            }

        }

to retrieve:

  <v-flex class="ma-2" v-for="casee in cases" :key="casee.id" lg3 xs12 md6 sm4> 

                <img v-if="casee.image" :src="'/storage/' + casee.image" alt="Case Image">

 mounted(){
        this.getcases();
    },
    methods:{
       async getcases(){
            try {
                const response = await axios.get('http://127.0.0.1:8000/api/cases');
                this.cases = response.data.cases;
                console.log(this.cases);
            } catch (error) {
                console.log(error);
            }
        },

everything works fine except for the image. it returns the error Cannot GET /storage/public/CQu7g4X98APkiMSbCGlqyiJhaXzLaEk8P0pZXaD3.jpg when i try to retrieve it

aliana
  • 47
  • 5
  • 1
    Does this answer your question? https://stackoverflow.com/questions/50730143/laravel-storage-link-wont-work-on-production – cengsemihsahin Feb 05 '23 at 21:32
  • @cengsemihsahin sadly,no – aliana Feb 05 '23 at 21:34
  • 1
    You have an error somewhere related to the `public` folder. It should be `/storage/FILENAME.jpg`, not `/storge/public/FILENAME.jpg`. Try changing the URL and see which URL works for loading the image – matiaslauriti Feb 05 '23 at 21:39
  • @matiaslauriti in my database it is public/CQu7g4X98APkiMSbCGlqyiJhaXzLaEk8P0pZXaD3.jpg but in the network tab returns Cannot GET /storage/public/uA9HtVHw8Ihg6xkglrbsflK5POXdCBCwhbtqqbpR.jpg and when i try to check the URL in the server it all returns 404 not found – aliana Feb 05 '23 at 21:46

3 Answers3

0

Make sure that the storage directory is correctly linked to the public. You can run this command to make it automatically:

php artisan storage:link
Daniel
  • 2,621
  • 2
  • 18
  • 34
0

Frontend couldn't access filesystem as "/storage/public/FILENAME.jpg".

If you are based on Laravel 9.x, and didn't change any filesystem default settings, your file will stored under "<project root>/storage/app/public/", it's filesystem default path, but frontend can only access your "<project root>/public/" folder, do check list as below might help you slove issue.

1.Make sure you executed php artisan storage:link command, and it will created a symbolic link from your storage path to public path.

If you didn't change settings, it will create link from "<project root>/storage/app/public" to "<project root>/public/storage", once you done command you can see your storage folder under public folder.

You can access "<APP_URL>/storage/FILENAME.jpg" to see if link create success or not, if you ain't get 404 means your link created as well as it should be.

2. Use laravel helper to generate storage url.

Use the asset() helper create a URL to the files.

Your files will under "<project root>/public/storage" after step 1, and your nginx root will access public as default, so you don't need public as your url path anymore.

asset('storage/FILENAME.jpg');
// output will be "<APP_URL>/storage/FILENAME.jpg"

3. (Not required) Check if laravel cached your view.

For some new developer of laravel didn't notice that laravel will cached your view, and they keep thinking that code doesn't work.

You can easily check if laravel cached view by php artisan about command if you are using latest laravel version, and use php artisan view:clear to clear view cache.

Charlie
  • 287
  • 11
  • thank you for your detailed answer!, i did everything as mentioned and now i can acess http://127.0.0.1:8000/storage/uA9HtVHw8Ihg6xkglrbsflK5POXdCBCwhbtqqbpR.jpg in my backend which means the image is stored correctly i guess ?however in my frontend Case Image still returns Cannot GET /storage/public/CQu7g4X98APkiMSbCGlqyiJhaXzLaEk8P0pZXaD3.jpg. you help would be greatly appreciated!! – aliana Feb 06 '23 at 09:11
  • Because you are saving wrong data in your database, just saving your file as FILENAME.jpg without public prefix. – Charlie Feb 06 '23 at 09:48
  • If you need a quick solution, replace your `'image' => $path` to `'image' => basename($path)`. – Charlie Feb 06 '23 at 09:54
  • this time it returns Cannot GET /storage/3EnhcRaPqah3G03o2k7QfhLZTjlfoHJOSqrNpaoH.jpg – aliana Feb 06 '23 at 10:05
  • Can you see your storage folder under your public folder? Correctly stored doesn't means it able to access. – Charlie Feb 06 '23 at 10:10
  • both public/storage and storage/app/public does contain the images i upload and the http://127.0.0.1:8000/storage/img.jpg displays the image well – aliana Feb 06 '23 at 10:13
  • Oh... ok. That's means backend issue already solved. There might be another issue when frontend binding. Can you check src url is correct or not? – Charlie Feb 06 '23 at 10:22
  • i did the steps you mentioned and some other configurations and now it works! thank you so much – aliana Feb 06 '23 at 10:24
0

heres how i solved it if anyone comes across this issue : based on the previous answers:

1. php artisan storage:link

  1. replace 'image' => $path to 'image' => basename($path).

3.<img :src="'http://127.0.0.1:8000/storage/' + casee.image" alt="Case Image">

aliana
  • 47
  • 5