Why If does not work in my code?

Hi,

I made a component for uploading images. This component uploads images but if does not work! what is the problem? It should show the upload result after the uploading finished!

 <template>

    <h1>Uploading an Image!</h1>

    <p>This component demonstrates Uploading Image to server.</p>
    <p v-if="!uploadResult"><em>uoloading...</em></p>
    <div v-if="uploadResult">{{this.uploadResult}} </div>

    <div>
        <form>
            <!--<input type="text" value="" v-model="projectName" placeholder="please enter the project name." />-->
            <input type="file" v-on:change="getFile($event)" />
            <button v-on:click="submitForm($event)">Upload</button>
        </form>

    </div>



</template>

   <script>
        
        export default {

            name: "Upload1",
            data() {
                return {

                    
                    selectedFile: " ",
                    uploadResult: " ",
                    fileList: []
                }
            },

            methods: {

                getFile(event) {
                    this.selectedFile = event.target.files[0];
                    console.log(this.file);
                },

                submitForm(event) {
                    event.preventDefault();
                    let formData = new FormData();
                    formData.append("ImageData.File", this.selectedFile);

                    fetch('/api/Image', {
                        method: 'POST',
                        body: formData
                    }).then(resposne => resposne.json())
                        .then(data => {
                            console.log(data);
                            this.uploadResult=  "File " + data.fileName + " successfully uploaded."

                            this.getList();

                        });

                },
                getList() {
                    fetch('api/Image')
                        .then(response => response.json())
                        .then(data => this.fileList = data)

                }
            },
            mounted() {
                this.getList();
            }

        };

    </script>

regards,
Saeed

Try this instead

data() {
  return {
    selectedFile: " ",
    uploadResult: null,
    fileList: []
  }
},
<p v-if="!uploadResult"><em>uoloading...</em></p>
<div v-else>{{ uploadResult }} </div>

unfortunately, nothing happens :neutral_face:

There’s no reason the v-if/else shouldn’t work if uploadResult gets set. There must be something else going on. Are you getting any console errors? Can you recreate the issue in a jsfiddle?

It’s a VUE/ASP.net Core template. It perfectly uploads but shows no result.
If you would like I can send you the source code.

Here you can read more about the template:
https://medium.com/js-dojo/template-vue-js-3-0-asp-net-core-5-0-visual-studio-2019-a18dd43b076b

regards,

The problem is with fetching.
Vue, in my experience, will not wait for something to be fetched. On mounted, it will run the ‘this.getList()’, but once it see’s the fetch – with no data – it will continue. The only data it sees is a promise, not any images.
Somewhere you will need to tell it to await the fetch command. My guess is you would want to make the getList async, then mark the fetch to await.
This wont automatically be reactive if the page doesn’t refresh though. It would need to be refreshed to still display content since the only time getList is referenced is in mounted. Either force it to refresh after upload, or periodically check for changes. Whatever works for you.
A vue fiddle would be nice.

Edit: you also seem to want to make the submitform await the fetch as well. Again, it only runs once, and the data it is being given is a PROMISE that something will be returned. If you want content, you need to wait until the content is gathered.

It’s not.

OP sets this.fileList in the response Promise chain, but OPs issue isn’t related to the fileList, it’s related to this.uploadResult and his v-if statement.

OP runs this.getList within the response chain of the fetch within submitForm which will get the latest data. Never force a page refresh, this defeats the purpose of the reactive nature of Vue.

Again, OP is using the promise chain. He could use async/await as an alternative, but he’s not doing anything wrong here by using thenable’s.

So what’s his issue then? The code works fine.
As a note, setting uploadResult to " " is truthy value, and “” is falsy.

Hard to say without a jsfiddle replicating the issue. On the surface I don’t see anything inherently wrong. There are a few formatting/spelling mistakes, but nothing I would expect to stop rendering. It could be the response data for all we know - e.g. data.fileName could be undefined, but OP hasn’t confirmed any console errors.

Yep, which is why I recommended using null as a default value.

That’s why I said it as a “note”. I’m not sure why null wouldn’t work, as my test changing it to “” and null did the same.
At this point I still don’t know what the issue is. It could have been clearer.

This is the right answer (first answer)
The problem was my carelessness! :neutral_face:

There is another answer on:

And also CodeSandbox:

Thanks for all help and support.

I guess I didn’t notice that. I believe when referencing things inside the ‘html’ template you don’t use this. But when you are referencing it in the scripts, you need to use this. Hard to spot mistake ngl

1 Like