Nativescript Vue simple example create() mounted() never fire - fetch

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>

There are some problems I identify in your code:
the correct lifecycle hook name is created, not create
the posts list should be inside data:
data() {
return {
posts: []
};
},
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.

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>

Related

Data not being displayed from firebase v9 - React Native

I want to display all the data, fetched from firestore, to be displayed through a component in React Native.
There are 3 chat names in the database.
I am expecting to Display the name of the chats from firestore. But when I tried, it showed me 3 components with no header. (Which is the main thing)
It makes me clearly understand that it is able to fetch the data from firestore, but is unable to put the data into an array.
According to the answer of Problem while upgrading a code snippet from firebase v8 to firebase v9, I have used the following code:
In the screens/Home.js file:
// Home.js
import { collection, onSnapshot } from "firebase/firestore";
import CustomChatList from '../components/CustomChatList';
import { db } from '../firebase';
import React, { useEffect, useLayoutEffect, useState } from 'react'
const [chats, setChats] = useState([])
useEffect(() => {
const colRef = collection(db, "chats")
onSnapshot(colRef, (snapshot) => {
setChats(
snapshot.docs.map((doc) => ({
id: doc.id,
data: doc.data(),
}))
)
});
return unsubscribe;
}, [])
return(
<div>
{chats.map(({ id, data: { chatName } }) => (
<CustomChatList id={id} chats={chatName} />
))}
</div>
)
In the components/CustomChatList.js file:
import { View, Text } from 'react-native'
import React from 'react'
import { ListItem, Avatar } from 'react-native-elements'
const CustomChatList = ({ id, chatName, enterChat }) => {
return (
<ListItem key={id} bottomDivider>
<Avatar rounded source={{ uri : 'https://toppng.com/uploads/preview/roger-berry-avatar-placeholder-11562991561rbrfzlng6h.png'}} />
<ListItem.Content>
<ListItem.Title>
{chatName}
</ListItem.Title>
<ListItem.Subtitle numberOfLines={1} ellipsizeMode="tail">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
)
}
export default CustomChatList
As of now, I have not recieved any error yet. Only the ChatNames are not getting displayed. How can I solve this?

WordPress Gutenberg RichText, how can I set a default value with source: 'children' when using `multiline="p"`?

While registering a new block, I cannot set a default value if using a RichText with a multiline tag
attributes: {
header: {
type: 'string',
source: 'text',
selector: 'h2',
default: 'default',
},
text: {
type: 'array',
source: 'children',
selector: 'div',
default: 'Lorem Ipsum Dolor Sit Amet',
// also tested, same result
// default: ['Lorem Ipsum Dolor Sit Amet', 'test', 'test2'],
// default: () => <p>Lorem Ipsum Dolor Sit Amet</p>,
// default: [() => <p>Lorem Ipsum Dolor Sit Amet</p>],
},
},
edit: ({ attributes: { header, text }, setAttributes }) => {
const blockProps = useBlockProps()
return (
<div {...blockProps}>
<RichText tagName="h2" placeholder={'Header'} onChange={header => setAttributes({ header })} value={header} />
<RichText
tagName="div"
multiline="p"
placeholder={'Write here the description'}
onChange={text => setAttributes({ text })}
value={text}
/>
</div>
)
},
If I remove the multiline="p" line, I see the default text, but with it I don't see anything
Where's the error?
An alternative simplified way using the attributes to set a default for RichText with multiline="p" is:
attributes: {
...
text: {
type: 'string', // changed from array
source: 'children',
selector: 'div',
default: [<p>Lorem Ipsum Dolor Sit Amet</p>, <p>test</p>, <p>test2</p>]
}
I've been able to do it by using what you gather when you edit manually the text
default: [
{ type: 'p', props: { children: ['Lorem Ipsum Dolor Sit Amet'] } },
{ type: 'p', props: { children: ['test'] } },
],

Vuejs axios error when making post request

I'm new to vuejs and i'm following this tutorial
(https://www.youtube.com/watch?v=Wy9q22isx3U&t=3492s).
When i tried to make a post request i got this error (has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.)
I could console.log(res.data) but i couldn't put it inside todos[] array.
addtodo(newTodo){
const {title,completed} = newTodo;
axios.post('https://jsonplaceholder.typicode.com/todos',{
title,
completed
})
.then(res => {
this.todos = this.todos.push[res.data];
//console.log(res.data);
})
.catch(err => console.log(err));
}
you are using .push() wrong, it is parenthesis not bracket.
new Vue({
el: "#app",
data: {
todos:[{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
}]
},
methods: {
addtodo(newTodo){
const {title,completed} = newTodo;
axios.post('https://jsonplaceholder.typicode.com/todos',{
title,
completed
})
.then(res => {
this.todos.push(res.data);
console.log(res.data);
})
.catch(err => console.log(err));
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="addtodo({title:'New todo',completed:true})">
click to add todo
</button>
<ul>
<li v-for="todo in todos" :key="todo.id">{{todo.title}}</li>
</ul>
</div>
no need to this.todos = this.todos.push() just use
this.todos.push(res.data)

Trigger animation after page load in angular 8, ExpressionChangedAfterItHasBeenCheckedError

As the question suggests, I am trying to figure out a way to get an element animated after the page has been loaded. I have looked all over the place but there seem to be too many and no way to do this at the same time, I am hoping for some guidance. After the page is loaded in mobile the the logo should slowly animate towards the top-right and also scale down in size, if that makes sense.
I am looking for the Angular equivalent of $(document).ready(function() {}
As per suggestions, I have used ngAfterViewInit() but I still cannot get anything to work.
Below the index-section.component.html
<section class="index-section">
<div [#logoMoveResize]="load_completed ? 'initial' : 'end'" class="index-logo-wrapper" [class.hideOnLoad]="isTrue">
<figure>
<img src="assets/icons/logo_mobile.svg" alt="urbanwheels logo">
</figure>
</div>
<div class="index-media-wrapper">
<div class="media-container">
<iframe src="https://player.vimeo.com/video/128014070?autoplay=1&color=ffffff&title=0&byline=0&portrait=0" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Itaque contra est, ac dicitis; Duo Reges: constructio interrete. Videsne quam sit magna dissensio?
</p>
</div>
</section>
And the index-section.component.ts
import { Component, OnInit, Inject, ViewChild } from '#angular/core';
import { trigger, state, animate, style, group, query, transition } from '#angular/animations';
#Component({
selector: 'app-index-section',
templateUrl: './index-section.component.html',
styleUrls: ['./index-section.component.scss'],
animations: [
trigger('logoMoveResize', [
state('initial', style({
transform: 'translateX(0%) translateY(0%) scale(1)',
})),
state('end', style({
transform: 'translateX(25%) translateY(-25%) scale(.3)',
})),
transition('initial <=> end', [animate('1s')]),
])
]
})
export class IndexSectionComponent implements OnInit {
load_completed = true;
innerWidth: any;
ngOnInit() {
this.innerWidth = window.innerWidth;
}
ngAfterViewInit() {
if ( this.innerWidth < 1000 ) {
this.load_completed = false;
}
}
}
This the error I am getting:
set a variable in component.ts
#Component({
selector: 'app-some',
templateUrl: './some.component.html',
styleUrls: ['./some.component.scss'],
animations: [
trigger('fadeInOut', [
state('void', style({
opacity: 0
})),
transition('void <=> *', animate(1000)),
]),
trigger('EnterLeave', [
state('flyIn', style({ transform: 'translateX(0)' })),
transition(':enter', [
style({ transform: 'translateX(-100%)' }),
animate('0.5s 300ms ease-in')
]),
transition(':leave', [
animate('0.3s ease-out', style({ transform: 'translateX(100%)' }))
])
])
]
})
export class SomeComponent implements OnInit {
load_completed = false;
ngOnInit(){
}
ngAfterViewInit(){
load_completed = true;
}
}
And in you component.html
<div [#fadeInOut]="load_completed"> some random element you want to animate </div>
As above example you can just animate when you need based on the condtion
This answer has provided me with info I need in regards to the question. As #Kevin LeStarge suggested my work around was:
setTimeout(()=> {
this.load_completed = true;
}, 0);
Or as #Lijo suggests using the AfterContentChecked life cycle hook:
import { ChangeDetectorRef, AfterContentChecked} from '#angular/core';
constructor(
private cdref: ChangeDetectorRef) { }
ngAfterContentChecked() {
this.cdref.detectChanges();
this.load_completed = true;
}
use ngAfterViewInit hook of angular to apply animation to the element.
I am looking for the Angular equivalent of $(document).ready(function() {}
the equivalent is
constructor(private zone: NgZone) {
this.zone.onStable.pipe(
// don't keep the stream open
first()
).subscribe(() => /* zone is stable, do something */)
}
You can use Angular Resolve - Interface that classes can implement to be a data provider. A data provider class can be used with the router to resolve data during navigation. The interface defines a resolve() method that will be invoked when the navigation starts. The router will then wait for the data to be resolved before the route is finally activated.
For more details -
https://angular.io/api/router/Resolve

Angular 2: Get JSON content from HTTP response

I have received a JSON object (i think) from my HTTP Web Service but struggling to pull out the strings.
https://jsonplaceholder.typicode.com/posts/1 gives me
{
"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"
}
My code:
I set up a service:
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class MyNewServiceService {
constructor(private http: Http) {}
getHTTP() {
return this.http.get('https://jsonplaceholder.typicode.com/posts/1').map(
response => response.json());
}
}
Called it from my app.component, trying and failing tooutput to the screen via title.
import { Component} from '#angular/core';
import { MyNewServiceService } from './my-new-service.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [MyNewServiceService]
})
export class AppComponent {
title = 'app works!';
constructor(MyNewServiceService: MyNewServiceService){
MyNewServiceService.getHTTP()
.subscribe(
JSONtitle => this.title = JSONtitle,
error => console.error('Error: ' + error),
() => console.log('Completed!')
);
}
}
I ended up outputting [object Object] to the screen.
I tried outputting it to console but got 'undefined' assuming service hadn't finished yet in angular2 lifecycle. So i created a new class and tried to cast with it but no luck
export class JsonResponseClass {
constructor(
public userid:number,
public id:string,
public title:string,
public body:string
)
{}
}
Template is simple...
<h1>
{{title}}
</h1>
How do i get my strings from the json?
You're returning response body as a mapping result from the service. Suiting the situation, you can access needed properties in your component as follows:
constructor(MyNewServiceService: MyNewServiceService){
MyNewServiceService.getHTTP()
.subscribe(
resBody => this.title = resBody.title,
error => console.error('Error: ' + error),
() => console.log('Completed!')
);
}
Btw, convention tells us to keep instance variables camelCased, so you can differentiate instance from the class itself:
constructor(private myNewServiceService: MyNewServiceService){
myNewServiceService.getHTTP()
.subscribe(
resBody => this.title = resBody.title,
error => console.error('Error: ' + error),
() => console.log('Completed!')
);
}

Resources