Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading state async #20

Closed
xeor opened this issue Oct 26, 2018 · 4 comments
Closed

Loading state async #20

xeor opened this issue Oct 26, 2018 · 4 comments

Comments

@xeor
Copy link

xeor commented Oct 26, 2018

I'm trying to load the initial state using axios, but I think it is too late to load the state when axios are able to get it from the backend.

Based on what I can read in the source, everything in vue-golden-layout that deals with loading the state happens in the mounted() function.. I have been playing with vue route-guard (beforeRouteEnter), the only place I can populate this, would be after the vue-golden-layout is already loaded..

Will using a guard (https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards) be a way? Is there a complete other way of doing this? Or am I missing something?
I guess setting localStorage inside a guard might work.. But now sure if that is the way to do it..?

@eddow
Copy link
Collaborator

eddow commented Oct 28, 2018

Well,

Loading the state dynamically would be a feature to implement. It is not really in my priorities but anybody could do it easily - I will still check if I couldn't do it really fast.

If not, a workaround is this one :
A route's component can be a function that returns either a component either a Promise (of component ofc)
Therefore, it should be possible in the route call-back to require the state w/ Axios, and instanciate the component after reception.

@eddow
Copy link
Collaborator

eddow commented Oct 28, 2018

Wow - ok. Indeed no, it will not be implemented for the simple fact that golden-layout does not have it implemented neither.
Therefore, the only way to do it is the work-around, to create the component only after the AJAX return.

Also, the guards can be used also for the same purpose : to call the next function only after the ajax return.

@eddow eddow closed this as completed Oct 28, 2018
@xeor
Copy link
Author

xeor commented Oct 28, 2018

Thanks..

Here are tidbits of what I ended up with. I have to reload the whole page, tho, but thats ok for this simple usecase.

function loadGlConfig(next, name, reload) {
  if(!name) next()
  axios
    .get(`https://domain/api/v1/layouts/${name}/`)
    .then(response => {
      localStorage["gl"] = JSON.stringify(response.data.gl)

      next()
      if(reload) {
        // It is still important to call next() first, else the go(0) will end up refreshing us
        // to the wrong url.
        router.go(0)
      }
    })
    .catch(error => {
      Notify.create({
        message: "Unable to load layout..",
        detail: error.message
      });
    });
}

  beforeRouteUpdate (to, from, next) {
    loadGlConfig(next, to.params.layout, true)
  },
  beforeRouteEnter (to, from, next) {
    loadGlConfig(next, to.params.layout)
  },

@eddow
Copy link
Collaborator

eddow commented Oct 29, 2018

Indeed, I was not seeing how to do without a reload with the guards, hence my idea of using the route functionalities. Here, I quickly made a draft - that case can unfortunately not be used in my test application (as routes are used inside the golden-layout)
So, it is just for the idea as I didn't test nor even made it checked by a parser.

So, the component would have a constructor with a state parameter :

<template>
	<golden-layout @state="changedState" :state="state">
		<something />
	</golden-layout>
</template>
<script lang="ts">
import Vue from 'vue'
import {Component, Inject, Model, Prop, Watch} from 'vue-property-decorator'

@Component()
export default class MyLayout extends Vue {
	state: any
	constructor(state) {
		this.state = state;
	}
	changedState(state) {
		axios.put(...);
	}
	...
}
</script>

And here would be the definition of the route :

{
	path: `/MyLayout`,
	component: ()=> axios
		.get(`https://domain/api/v1/layouts/${name}/`)
		.then(response => {
			return new MyLayout(response.data.gl);
		})
		.catch(error => {
			Notify.create({
				message: "Unable to load layout..",
				detail: error.message
			});
			throw error; //To be sure Vue knows the component load has failed
		});
	})
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants