How to get data at the beginning in Vue page - firebase

My problem is I want to get data at the beginning of the vue page. I tried to put those codes in mount() but it's still too late. After searching I think maybe created() is a good place or any places before generating the html code. But as I need to import a function so it seems that I cannot use created(). So I am wondering what's the better option to do that?
Right now my code looks like this
<template>
{{ username }}
<template>
<script>
import firebase from 'firebase';
export default {
name: 'page',
data() {
return {
username = "whatever",
}
}
mounted() {
var firebaseConfig = {
// some code
};
firebase.initializeApp(firebaseConfig);
this.username = username from firebase
},
}
</script>
But when I reload the page it shows whatever instead of the username I get from the firebase.

The firebase function needs to resolve before you set the username property. Async the mounted function & await the firebase call

The data initialization looks a bit odd to me.
Usually data should be an Object
In Your case i would suppose it to look something like this:
data: {
username: 'whatever'
}
And further on there seems to be a missing , between data and mounted.
I created a fiddle that works
It is not a sfc but i think it is enough to make things clear.

Related

how to pass data with next router without showing it in the URL?

I am using next router and I want to pass data to another page but I don't want the data to be shown in the URL
I am new to nextjs and I want to navigate between pages using router.push(). I found this solution in the official documentation
Let's say that I have a button once clicked I want ton navigate to another page and pass an object myObject to it.
import { useRouter } from "next/router";
const router = useRouter();
const myObject = {
proprety1: "example1",
proprety2: "example2",
proprety3: "example3"
}
<button>
onClick={()=>{
router.push({
pathname: '/next-page',
query: { data: JSON.stringify(myObject) },
})
}}
</button>
then in the next-page I get this as URL :
http://localhost:3000/next-page?data=%7B"proprety1"%3A"example1"%2C"proprety2"%3A"example2"%2C"proprety3"%3A"example3"%7D
this works fine to be clear, but it is really ugly, not just that, I don't want data to be showen to users.
is there another solution for this? thank you in advance
I believe you can use the second parameter as in the router.push function in order to accomplish what you want.
router.push(url, as, options)
See documentation.

Passing data to props after asynchronous call in Vue

I have set up a bare bones vue project to show the problem. The only thing I added was the axios package. The problem is when I try to set the property of child component after an asynchronous call I cant read that property in the component. If you look at the code you can see I console log several times to show when I can get the data and when I cant. Please help me figure out what im missing here.
Parent
<template>
<div id="app">
<HelloWorld :test_prop="testData" :test_prop2="testData2" :test_prop3="testData3" test_prop4="I work also"/>
<div>{{testData5}}</div>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import axios from 'axios';
export default {
name: 'app',
components: {
HelloWorld
},
data() {
return {
testData: '',
testData2: 'I work just fine',
testData3: '',
testData5: ''
}
},
created: function(){
var self = this;
this.testDate3 = 'I dont work';
axios.get('https://jsonplaceholder.typicode.com/posts/42').then(function(response){
//I need this one to work
self.testData = 'I dont work either';
self.testData5 = 'I work also';
});
}
}
</script>
Child
<template>
</template>
<script>
export default {
name: 'HelloWorld',
props: ['test_prop', 'test_prop2', 'test_prop3', 'test_prop4'],
data() {
return {
comp_data: this.test_prop,
comp_data2: this.test_prop2,
comp_data3: this.test_prop3,
comp_data4: this.test_prop4
}
},
created: function(){
console.log(this.test_prop);
console.log(this.test_prop2);
console.log(this.test_prop3);
console.log(this.test_prop4);
}
}
</script>
Your console.log inside created hook will show you the initial state of this variables in Parent component. That's because Parent's created hook and Child's created hook will run at the same time.
So, when you solve your promise, Child component was already created. To understand this behavior, put your props in your template using {{ this.test_prop }}.
To solve it, depending on what you want, you can either define some default value to your props (see) or render your child component with a v-if condition. That's it, hope it helps!
On Vue created hook only the initial values of properties passed from main component. Therefore later updates (like your example "after ajax call") in main component will not effect to child component data variables because of that already child created hook take place.
If you want to update data later one way you can do like this:
watch: {
test_prop: function(newOne){
this.comp_data = newOne;
}
}
Adding watcher to property changes will update the last value of property from main component.
And also edit the typo this.testDate3. I guess it must be this.testData3

VueJS rendering data from REST service

I've attempted to render data from a http request to a component which is working fine, the issue is that it's null while the data is being fetched. While the data is null the console is throwing a TypeError until all the data is loaded and committed to the Vuex store.
All is working how I'd suspect, I'm just trying to figure how I can prevent the errors being thrown and to wait until all the appropriate data is fetched. I've seen others using v-if to check if the data is null which will work. It just seems tedious and that there surly is a better way to achieve the same outcome, without an application riddled with v-if statements checking every single state.
I came across this solution but it's still not working how I thought it would, I'm still receiving the same console errors. Am I using these key words correctly and are they in the correct location? since nothing has changed with every variation I've tried.
Vuex Action:
const actions = {
getThread ({ commit }, payload) {
Vue.http
.get(`http://localhost:9000/threads/${payload.id}`)
.then(async response => {
commit(FETCH_THREAD, await response.data)
})
}
}
This is within my vue file calling upon the action:
created () {
this.$store.dispatch('getThread', {id: '59280ab5acbafb17af9da902'})
}
I assume you are trying to display something from your store in your template. The problem is, Vue cannot render something that does not exist yet. The solution is to check whether the data exists or not.
Let's take this component example:
<template>
<div>
{{ someObject.name }}
</div>
</template>
<script>
export default {
data () {
return {
someObject: null
}
},
methods: {
fetchTheObject () {
this.someObject = {
id: 1,
name: 'My object'
}
}
},
created () {
setTimeout( () => {
this.fetchTheObject()
}, 3000)
}
}
</script>
As you can see, you will get an error in your console because someObject.name does not exist until fetchTheObject() has been called.
The solution is to put some v-if attribute to control that:
<template>
<div>
<span v-if="someObject === null">Fetching the object</span>
<span v-else>{{ someObject.name }}</span>
</div>
</template>
In general, you would want to display some spinner to show the user that something is loading...
Hope this helps
EDIT: And forget about the async await in your code, you don't need that here

Vue JS AJAX computed property

Ok, I believe I am VERY close to having my first working Vue JS application but I keep hitting little snag after little snag. I hope this is the last little snag.
I am using vue-async-computed and axios to fetch a customer object from my API.
I am then passing that property to a child component and rendering to screen like: {{customer.fName}}.
As far as I can see, the ajax call is being made and the response coming back is expected, the problem is there is nothing on the page, the customer object doesnt seem to update after the ajax call maybe.
Here is the profile page .vue file I'm working on
http://pastebin.com/DJH9pAtU
The component has a computed property called "customer" and as I said, I can see in the network tab, that request is being made and there are no errors. The response is being sent to the child component here:
<app-customerInfo :customer="customer"></app-customerInfo>
within that component I am rendering the data to the page:
{{customer.fName}}
But, the page shows no results. Is there a way to verify the value of the property "customer" in inspector? is there something obvious I am missing?
I've been using Vue for about a year and a half, and I realize the struggle that is dealing with async data loading and that good stuff. Here's how I would set up your component:
<script>
export default {
components: {
// your components were fine
},
data: () => ({ customer: {} }),
async mounted() {
const { data } = await this.axios.get(`/api/customer/get/${this.$route.params.id}`);
this.customer = data;
}
}
</script>
so what I did was initialize customer in the data function for your component, then when the component gets mounted, send an axios call to the server. When that call returns, set this.customer to the data. And like I said in my comment above, definitely check out Vue's devtools, they make tracking down variables and events super easy!
I believed your error is with naming. The vue-async-computed plugin needs a new property of the Vue object.
computed: {
customer: async function() {
this.axios.get('/api/customer/get/' + this.$route.params.id).then(function(response){
return(response.data);
});
}
}
should be:
asyncComputed: {
async customer() {
const res = await this.axios.get(`/api/customer/get/${this.$route.params.id}`);
return res.data;
}
}

Ionic2 tabs/app,ts passing value

I need to pass value from tabs.ts to each page of tabs. So I have something like this:
constructor(public navParams: NavParams) {
...// config
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// If there's a user take him to the home page.
this.user = [];
this.user.push(user);
this.rootPage = HomePage;
} else {
// If there's no user logged in send him to the LoginPage
this.rootPage = LoginPage;
}
});
}
this.tab1Root = HomePage;
this.tab4Root = ProfilePage;
How to pass value (user) to each page of tabs? I tried with few combinations of this code but doesnt work (getting some erros - e.g If I put this.tab1Root... to onAuthStateChanged method, then it gives me: "Maximum call stack size exceeded"). Here are docs: http://ionicframework.com/docs/v2/api/components/tabs/Tab/ - I understand 90% of this but still dont know how I should pass this value...
My second question - is there any better way to take current user and pass him as value to each page? Will be better if I use provider or something?
Third question: it is good to have this code in tabs.ts than in app.ts?
Thanks!
You can use [rootParams] attribute in ion-tab
<ion-tab ... [rootParams]="user"></ion-tab>
In tab file:
constructor(navParams: NavParams) {
console.log("Passed params", navParams.data.user);
}
Second way is using events: http://ionicframework.com/docs/v2/api/util/Events/
It allows you to share data between any of your pages.
Provider is a good option.
It depends. Better way is to make an authorization once - using provider inside app.ts - when app starts.

Resources