I have created a basic project and simply want to pull a list of greetings from Google Firestore instead of using the default static array of greetings.
My greeting.js
file looks like this:
import { LightningElement, track, api, wire } from 'lwc';
import { getGreetings } from '../../../models/greeting.js';
const SPEED_CLASS_MAP = {
slow: 'fade-slow',
fast: 'fade-fast',
medium: 'fade-medium'
};
const DEFAULT_SPEED = 'medium';
export default class Greeting extends LightningElement {
@track animationSpeed = DEFAULT_SPEED;
@track index = 0;
@track isAnimating = true;
@wire(getGreetings, {})
greetings = [];
@api
set speed(value) {
if (SPEED_CLASS_MAP[value]) {
this.animationSpeed = value;
} else {
this.animationSpeed = DEFAULT_SPEED;
}
this.isAnimating = true;
}
// Return the internal speed property
get speed() {
return this.animationSpeed;
}
// Get the current greeting
get greeting() {
return this.greetings[this.index];
}
// Map slow, medium, fast to CSS Animations
get animationClass() {
if (this.isAnimating) {
return SPEED_CLASS_MAP[this.speed];
}
return 'hide';
}
//Handle the animation ending, update to next hello
handleAnimationEnd() {
this.isAnimating = false;
this.index = (this.index + 1) % this.greetings.length;
setTimeout(() => this.updateGreeting(), 500);
}
// Update to the next greeting and start animating
updateGreeting() {
this.isAnimating = true;
}
}
And my models/greeting.js
file looks like so:
import { register, ValueChangedEvent } from '@lwc/wire-service';
import firebase from '../firebase.js';
const db = firebase.firestore();
export function getGreetings(config) {
return getObservable(config)
.map(makeReadOnlyMembrane)
.toPromise();
}
register(getGreetings, function getGreetingsWireAdapterFactory(eventTarget) {
let subscription;
let config;
let greetings;
// Invoked when config is updated.
eventTarget.addListener('config', newConfig => {
// Capture config for use during subscription.
config = newConfig;
});
// Invoked when component connected.
eventTarget.addListener('connect', () => {
// Subscribe to stream.
subscription = getObservable(config)
.map(makeReadOnlyMembrane)
.subscribe({
next: data =>
wiredEventTarget.dispatchEvent(
new ValueChangedEvent({ data, error: undefined })
),
error: error =>
wiredEventTarget.dispatchEvent(
new ValueChangedEvent({ data: undefined, error })
),
});
// Get the data from Firestore:
db.collection("greetings")
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
let data = doc.data();
if (data.greeting != undefined) {
greetings.push(data.greeting);
}
});
wiredEventTarget.dispatchEvent(
new ValueChangedEvent({ data: greetings, error: undefined })
);
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
});
// Invoked when component disconnected.
eventTarget.addListener('disconnect', () => {
// Release all resources.
subscription.unsubscribe();
});
});
My firebase.js
file looks like so:
import firebase from 'firebase/app';
import 'firebase/firestore';
const firebaseConfig = {
apiKey: "<insert-api-key-here>",
databaseURL: "https://<insert-project-id-here>.firebaseio.com",
projectId: "<insert-project-id-here>",
appId: "<insert-app-id-here>"
};
firebase.initializeApp(firebaseConfig);
export default firebase;
But, the firestore call never fires.
I haven't been able to find any examples on calling external (asynchronous) APIs using @wire and I'm not fully grasping how it works anyway, so I'm not event sure if I've put the API call in the right place.
If I do the firestore call in connectedCallback()
it works fine.
Has anyone had any experience with this? How do I do external Rest API calls using @wire decorator?