-1

I have a component, lets call component 1. A method in component1 makes an axios.post request and the server returns a bunch of data. When data is loaded, a new button appears. When this button is clicked, it will be navigated to another route with another component, let call this component2. Now some of the loaded data from component1 needs to transferred to component2 and should be opened in new tab. Below is the code:

<script>
import axios from 'axios';
export default {
    name: "CheckStandard",
    data() {
        return {
            standard: '',
            time: {},
            programs: {},
            example: {},
        }
    },
    methods: {
        checkData(){
            let std= {
                std: this.standard,
            }
            axios.post('http://localhost:3000/postdata', std)
            .then(res => {
                if (res.status === 200) {
                    if (res.data === 0) {
                        this.invalidID = "This Standard does not exist"
                    }
                    else {
                       
                       let data = res.data
                       
                       this.time = res.data["Starttime"];
                       this.programs = res.data["program"]  
                       this.example = res.data["example"]  
                }

            }).catch(error => {
                console.log(error);
                this.error = error.response
            })
        },

}
 goToPictures(){
           let route = this.$router.resolve({
                name:'ProgramCheckList',
                params: {
                    programs: this.programs,
                    time: this.time,
                    example: this.example
                }
            })
            window.open(route.href,'_blank')
        },
    }
}
</script>

The function goToPictures is the function that is invoked after clicking the button. Now in this function goToPictures I have defined the route to navigate to another tab. But the problem the data in the params which it should carry is lost. I tried with $router.push ofcourse it works but it is not to open in new tab. Below is the code for the same:

    goToPictures(){
       this.$router.resolve({
            name:'ProgramCheckList',
            params: {
                programs: this.programs,
                time: this.time,
                example: this.example
            }
        })
    },
}

Since I am new to vue, I have tried my best to look for an answer for this, even I have came across some posts in several forums mentioning, it is may be not be possible even, instead advised to use vuex. But I still wanted to post it, maybe we have a solution now or any other idea. Thanks

  • Maybe pass the standard as a query parameter and have the ProgramCheckList component do the axios request on mounted instead? I don't think even vuex can hold that data if you open new window. – artoju Aug 20 '20 at 11:56
  • @artujo it takes lot of time for this particular request, we cannot do that. But if can also help me to how to retain the data of the checkStandard component after navigating back from ProgramCheckList component will also solve the issue. – Boomerang20thCentury Aug 20 '20 at 12:14

2 Answers2

1

The problem you're seeing stems from the fact that, when you open a new window, Vue is basically going to re-render your components as if you hit refresh. Your Component 2 has props that it can only inherit from another component, and as such, it has no possible way of knowing what the props it needs to use are.

To illustrate in simple terms what's happening:

The user navigates to Component 1. They click the button, which makes the GET request. You now have some data that you can pass onto Component 2 as props.

In a regular environment, the user would simply click on the link leading to Component 2, and the props would be passed on normally, and everything would work as intended.

The problem in your situation is that Component 2 depends on Component 1 for its data. By navigating directly to the Component 2 route (in this situation, opening a new window is functionally identical to a user copy/pasting the url into the adress bar), Vue never has the chance of interacting with Component 1, and never gets told where to get the props it needs to populate Component 2.

Overcoming the issue

There's a few things you can do here to overcome this issue. The most obvious one is to simply open Component 2 as you would normally, without opening a new window, but keep in mind that even if you do this, should a user copy/paste the URL where Component 2 is, they'll run into the exact same issue.

To properly deal with the issue, you have to specify a way for Component 2 to grab the data it needs. Since the data is already fetched, it makes sense to do this in the created() or mounted() hooks, though if you wanted to you could also deal with this in Vue Router's beforeRouteEnter() hook.

Vuex

While you don't necessarily need a state management tool like Vuex, it's probably the simplest way for your needs. When you grab the data from Component 1, store it and access it from the Component 2 mounted() hook. Easy-peasy.

localStorage()

Alternatively, depending on how the data is being served, you could use localStorage(). Since you're opening a new window, sessionStorage() won't work. Do note that localStorage() can only hold strings and nothing else, and isn't necessarily available in every browser.

Sensanaty
  • 894
  • 1
  • 12
  • 35
  • The things you mentioned in the section, **Overcoming the issue**, I have already implemented it. It is working fine. The probleem is when user hits the back button to go to Component 1, the data from component 1 is lost. Since i did not mention before. In component 1 a table is created soon after data is received from server. So if the user want s to see the table again, after hitting back button, the table is gone. So he has to do the post request again to see the table. – Boomerang20thCentury Aug 20 '20 at 13:35
  • If I also get a solution how I can save the data so the user see the tablee after hitting back button, then also it is negotiable. May be in this case I wwill have to use LocalStorage. Or if there is any other solution, kindly refer it. – Boomerang20thCentury Aug 20 '20 at 13:37
0

You can store the data to a global variable and use that in the newly opened window. Asked here Can I pass a JavaScript variable to another browser window?

Provided the windows are from the same security domain, and you have a reference to the other window, yes.

Javascript's open() method returns a reference to the window created (or existing window if it reuses an existing one). Each window created in such a way gets a property applied to it "window.opener" pointing to the window which created it.

Either can then use the DOM (security depending) to access properties of the other one, or its documents,frames etc.

Another example from same thread:

var thisIsAnObject = {foo:'bar'};
var w = window.open("http://example.com");
w.myVariable = thisIsAnObject;
//or this from the new window
var myVariable = window.opener.thisIsAnObject;
artoju
  • 1,612
  • 12
  • 12