0

Following is a very simple Nativescript Vue example from the starter. As it appears below, it displays the list of 5 post titles.

So above test is good to start as long as I only use computed to return data to template. However, if I attempt to use the create() or mounted() event/lifecycle hooks to set the posts property, I get nothing in the display. The console.log lines never display the message so they're never firing. Why not?

Also, if I try to use the fetch (call my fetchPosts() method) to pull posts from the test restapi, I get no data and console.error shows nothing. Why not?

<template>
<Page class="page">
    <ActionBar class="action-bar">
    <Label class="action-bar-title" text="Home"></Label>
    </ActionBar>
    <ScrollView>
    <StackLayout class="home-panel">
        <!--Add your page content here-->
        <Label v-for="post in posts" :text="post.title" :key="post.id"/>
    </StackLayout>
    </ScrollView>
</Page>
</template>

<script>
export default {
//   posts: [],
//   create() {
//     console.log("create event fired");
//     this.posts = this.getPosts();
//   },
//   mounted() {
//     console.log("mounted event fired");
//     this.posts = this.getPosts();
//   },
computed: {
    posts() {
    //return this.fetchPosts();
    return this.getPosts();
    }
},
methods: {
    fetchPosts() {
    fetch("https://jsonplaceholder.typicode.com/posts")
        .then(res => res.json())
        .then(res => {
        console.log("fetch response", res);
        return res;
        })
        .catch(err => {
        console.error(err);
        return [{ id: 0, title: "Error: " + err }];
        });
    },
    getPosts() {
    return [
        {
        userId: 1,
        id: 1,
        title:
            "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
        body:
            "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
        },
        {
        userId: 1,
        id: 2,
        title: "qui est esse",
        body:
            "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
        },
        {
        userId: 1,
        id: 3,
        title: "ea molestias quasi exercitationem repellat qui ipsa sit aut",
        body:
            "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
        },
        {
        userId: 1,
        id: 4,
        title: "eum et est occaecati",
        body:
            "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit"
        },
        {
        userId: 1,
        id: 5,
        title: "nesciunt quas odio",
        body:
            "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque"
        }
    ];
    }
}
};
</script>

<style scoped lang="scss">
// Start custom common variables
@import "../app-variables";
// End custom common variables

// Custom styles
.fa {
color: $accent-dark;
}

.info {
font-size: 20;
}
</style>
Locohost
  • 1,682
  • 5
  • 25
  • 38
  • In [this](https://play.nativescript.org/?template=play-vue&id=ngITmc&v=4) basic example I just wrote it seems to work. Maybe you have some errors, not necessary related to vue lifecycle hooks. – Jorj Feb 03 '19 at 16:53
  • Thanks for the reply and example @Jori. I'm running in VS Code and it does build and run fine. I see no errors anywhere. However I can never produce any console.log message – Locohost Feb 03 '19 at 17:06
  • Ok so if I used the Nativescript Sidekick app, I CAN see console.log output and it appears the lifecycle events do fire. Not sure why I can't see the console.log output anywhere in VS Code. Where *should* I see them? – Locohost Feb 03 '19 at 17:13
  • So using Nativescript Sidekick app I can see device console output and I can see that the `fetch` *is* returning data when called from either `mounted()` or `created()`. The `posts` property *is* getting set. However the template never refreshes to display the fetched posts. What is last "bind" piece I'm missing? – Locohost Feb 03 '19 at 17:27

2 Answers2

2

There are some problems I identify in your code:

  1. the correct lifecycle hook name is created, not create
  2. the posts list should be inside data:

    data() {
        return {
            posts: []
        };
    },
    
  3. the fetchPosts() doesn't return anything, but you expect to return the posts. You have to set the posts inside then callback:

    fetchPosts() {
        fetch("https://jsonplaceholder.typicode.com/posts")
            .then(res => res.json())
            .then(res => this.posts = res)
            .catch(err => console.error(err));
    }
    

    and this because fetch returns a Promise. Q: How to return data from Promise? A: You can't!

Full code:

<script>
export default {
    data() {
        return {
            posts: [{
                title: '1 Title',
                id: 1
            }]
        };
    },
    created() {
        console.log("create event fired");
        this.posts = this.fetchPosts();
    },
    mounted() {
        console.log("mounted event fired");
        this.fetchPosts();
    },
    methods: {
        fetchPosts() {
            return fetch("https://jsonplaceholder.typicode.com/posts")
                .then(res => res.json())
                .then(res => this.posts = res);
        }
    }
};
</script>

The code was tested here.

Jorj
  • 1,291
  • 1
  • 11
  • 32
  • 1
    Thanks @Jorij. It's working. I accepted your answer. I think the last piece was your #2 above. I didn't have my data() setup right. Plus, I never could see (still can't as I type) the lifecycle hooks firing in VS Code. But I do see the device console output in Nativescript Sidekick. So I'm over the hump. Thank you Jorj !!! – Locohost Feb 03 '19 at 18:33
  • Interesting note: You can't return the res/data from the promise.then and set `this.posts = this.fetchPosts()` in `mounted()`. That *does not work*. You *must* set `this.posts = res` inside the promise.then for it to work. Why is that? – Locohost Feb 03 '19 at 18:37
  • Nevermind "interesting note" above. It's not *interesting* at all :-/ You can simply return the promise then catch promise.then in the `mounted()`. I think so. I'll try it now. Should work fine. – Locohost Feb 03 '19 at 18:57
1

For me it is also not firing, instead of using mounted or created I added a loaded event on the page element

<template>
    <page @loaded="startMyApp">
    ......
</template>
<script>
  export default {
    data() {
      return {
      }
    },
   methods: {
        startMyApp()
        {
        }
  }
</script>
dejitaru
  • 31
  • 1
  • 1