proper use of onCompleted for GraphQL mutations - javascript

I want to run the query first. The query returns an id which is then required for the mutation. Currently, there's an issue with the order of how both things run from the handleSubmit(). If the mutation is successful, the console should print console.log('Checking');but that does not happen. The only output I get on the console is What's the Idand the value is probably something that was stored in one of my previous attempts. If the id was derived from this particular round of query, I would have seen Workingon the log, but that doesn't happen either.
const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery, {
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
},
onCompleted: () => getFriendId(),
});
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
},
] = useCreateUserRelationMutation({
variables: {
input: {
relatedUserId: Number(id),
type: RelationType.Friend,
userId: 5,
},
},
onCompleted: () => addFriend(),
});
const getFriendId = () => {
console.log('Working');
if (data) {
console.log(data);
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
}
} else {
if (error) {
setErrorMessage(error.message);
}
}
};
const addFriend = () => {
console.log('Whats the Id', Number(id));
if (addingFriendData) {
console.log('Checking');
console.log(addingFriendData);
}
if (addingFriendError) {
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
};
const handleSubmit = () => {
loadUsers();
createUserRelationMutation();
};
Before this, I was trying this:
const [id, setId] = useState('');
const [friendEmail, setFriendEmail] = useState('');
const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);
const [createUserRelationMutation, { data: addingFriendData, loading: addingFriendLoading, error: addingFriendError }] = useCreateUserRelationMutation();
const getFriendId = () => {
console.log('Email', friendEmail.toLocaleLowerCase());
loadUsers({
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
},
});
if (data) {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
}
addFriend();
};
const addFriend = () => {
console.log('Whats the Id', Number(id));
createUserRelationMutation({
variables: {
input: {relatedUserId: Number(id), type: RelationType.Friend, userId: 7 }
},
});
if (addingFriendData){
console.log('Checking')
console.log(data);
}
if(addingFriendError){
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
}
const handleSubmit = () =>
{getFriendId();};
However, in this case, the values of the id & other states weren't being updated timely. I was running a graphql query inside getFriendId()that returns an id, followed by a mutation (inside addFriend(), which uses the id, along with an input (email) that the user types in. The problem is that on the first attempt, the mutation works fine and with correct values. However, when I change the email address on the input and run the query/mutation again, the values from my previous attempt are being used.
In the second attempt, the mutation was still using the id that we got in the first attempt.
Edit:
onCompleted: (data) => getFriendId(data),
const getFriendId = (data: any) => {
console.log('Working');
if (data) {
console.log(data);
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
}
Updated Code:
const [friendEmail, setFriendEmail] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
},
] = useCreateUserRelationMutation();
const getFriendId = () => {
console.log('Email', friendEmail.toLocaleLowerCase());
loadUsers({
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
},
});
if (data) {
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
setId(data.users.nodes[0].id);
addFriend(data.users.nodes[0].id);
}
} else {
console.log('No data');
if (error) {
setErrorMessage(error.message);
}
}
//addFriend();
};
const addFriend = (idd: any) => {
console.log('Whats the Id', Number(idd));
createUserRelationMutation({
variables: {
input: {relatedUserId: Number(idd), type: RelationType.Friend, userId: 9 }
},
});
if (addingFriendData){
console.log('Checking')
console.log(data);
}
if(addingFriendError){
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
}
const handleSubmit = () =>
{
getFriendId();
};

You don’t need state to store ID, instead pass the Id to addFriend method like show below
const [friendEmail, setFriendEmail] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const _onLoadUserError = React.useCallback((error: ApolloError) => {
setErrorMessage(error.message);
}, []);
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
called: isMutationCalled
},
] = useCreateUserRelationMutation();
const addFriend = React.useCallback((idd: Number) => {
console.log('Whats the Id', idd);
createUserRelationMutation({
variables: {
input: { relatedUserId: idd, type: RelationType.Friend, userId: 9 }
}
});
}, [createUserRelationMutation]);
const getFriendId = React.useCallback((data: any) => {
console.log('Email', friendEmail.toLocaleLowerCase());
if (data) {
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
addFriend(Number(data.users.nodes[0].id));
}
}
}, [friendEmail, addFriend]);
const [loadUsers] = useLazyQuery(LoadUsersQuery, {
onCompleted: getFriendId,
onError: _onLoadUserError
});
const handleSubmit = React.useCallback(() => {
loadUsers({
variables: {
where: { email: friendEmail.toLocaleLowerCase() },
}
});
}, [loadUsers, friendEmail]);
if (!addingFriendLoading && isMutationCalled) {
if (addingFriendData) {
console.log('Checking')
console.log(data);
}
if (addingFriendError) {
console.log('errorFriend', addingFriendError.message);
setErrorMessage(addingFriendError.message);
}
}
Update
I have updated the above code, please refer to it. I'm assuming useCreateUserRelationMutation does not accept options as argument, if it accepts option then you could use onCompleted and onError just like loadUsers query.

Related

Rxdb infinitely pulling in replicateRxCollection

I'm working with rxdb and I have pull and push handlers for the backend I have used supabase
I have setup the code for replication as follows:
replication.ts
import { RxDatabase } from "rxdb";
import { RxReplicationPullStreamItem } from "rxdb/dist/types/types";
import { replicateRxCollection } from "rxdb/plugins/replication";
import { Subject } from "rxjs";
import { supabaseClient, SUPABASE_URL } from "src/config/supabase";
import { DbTables } from "src/constants/db";
import {
blockPullHandler,
blockPushHandler,
} from "./repilicationhandlers/block";
import { CheckpointType, RxBlockDocument, RxBlocksCollections } from "./types";
export async function startReplication(
database: RxDatabase<RxBlocksCollections>
) {
const pullStream$ = new Subject<
RxReplicationPullStreamItem<RxBlockDocument, CheckpointType>
>();
supabaseClient
.from(DbTables.Block)
.on("*", (payload) => {
console.log("Change received!", payload);
const doc = payload.new;
pullStream$.next({
checkpoint: {
id: doc.id,
updated: doc.updated,
},
documents: [doc] as any,
});
})
.subscribe((status: string) => {
console.log("STATUS changed");
console.dir(status);
if (status === "SUBSCRIBED") {
pullStream$.next("RESYNC");
}
});
const replicationState = await replicateRxCollection({
collection: database.blocks,
replicationIdentifier: "supabase-replication-to-" + SUPABASE_URL,
deletedField: "archived",
pull: {
handler: blockPullHandler as any,
stream$: pullStream$.asObservable(),
batchSize: 10,
},
push: {
batchSize: 1,
handler: blockPushHandler as any,
},
});
replicationState.error$.subscribe((err) => {
console.error("## replicationState.error$:");
console.log(err);
});
return replicationState;
}
blockPullHandler:
export const blockPullHandler = async (
lastCheckpoint: any,
batchSize: number
) => {
const minTimestamp = lastCheckpoint ? lastCheckpoint.updated : 0;
console.log("Pulling data", batchSize, lastCheckpoint);
const { data, error } = await supabaseClient
.from(DbTables.Block)
.select()
.gt("updated", minTimestamp)
.order("updated", { ascending: true })
.limit(batchSize);
if (error) {
console.log(error);
throw error;
}
const docs: Array<Block> = data;
return {
documents: docs,
hasMoreDocuments: false,
checkpoint:
docs.length === 0
? lastCheckpoint
: {
id: lastOfArray(docs).id,
updated: lastOfArray(docs).updated,
},
};
};
blockPushHandler:
export const blockPushHandler = async (
rows: RxReplicationWriteToMasterRow<RxBlockDocumentType>[]
) => {
if (rows.length !== 1) {
throw new Error("# pushHandler(): too many push documents");
}
const row = rows[0];
const oldDoc: any = row.assumedMasterState;
const doc: Block = row.newDocumentState;
console.log(row, oldDoc, doc);
// insert
if (!row.assumedMasterState) {
const { error } = await supabaseClient.from(DbTables.Block).insert([doc]);
console.log("Error 1", error);
if (error) {
// we have an insert conflict
const conflictDocRes: any = await supabaseClient
.from(DbTables.Block)
.select()
.eq("id", doc.id)
.limit(1);
return [conflictDocRes.data[0]];
} else {
return [];
}
}
// update
console.log("pushHandler(): is update");
const { data, error } = await supabaseClient
.from(DbTables.Block)
.update(doc)
.match({
id: doc.id,
replicationRevision: oldDoc.replicationRevision,
});
console.log("Error 2", error);
if (error) {
console.log("pushHandler(): error:");
console.log(error);
console.log(data);
throw error;
}
console.log("update response:");
console.log(data);
if (data.length === 0) {
// we have an updated conflict
const conflictDocRes: any = await supabaseClient
.from(DbTables.Block)
.select()
.eq("id", doc.id)
.limit(1);
return [conflictDocRes.data[0]];
}
return [];
};
But the issue is when I start the application and the pull handler is called correctly but it doesn't stop calling the pull handler and it sends continuous request one after another even after it has fetched the documents even when I set hasMoreDocuments to false It keeps sending requests and running the replicator. Is there something wrong with my configuration?
database.ts:
export const createDatabase = async () => {
const database = await createRxDatabase({
name: "sundaedb",
storage: getRxStorageDexie(),
});
await database.addCollections({
blocks: {
schema: blockSchema as any,
conflictHandler: conflictHandler as any,
},
documents: {
schema: documentSchema as any,
conflictHandler: conflictHandler as any,
},
});
database.blocks.preInsert((docData) => {
docData.replicationRevision = createRevision(
database.hashFunction,
docData as any
);
return docData;
}, false);
database.blocks.preRemove((docData) => {
console.log(" PRE REMOVE !!");
console.log(JSON.stringify(docData, null, 4));
const oldRevHeight = parseRevision(docData.replicationRevision).height;
docData.replicationRevision =
oldRevHeight + 1 + "-" + database.hashFunction(JSON.stringify(docData));
console.log(JSON.stringify(docData, null, 4));
return docData;
}, false);
database.blocks.preSave((docData) => {
const oldRevHeight = parseRevision(docData.replicationRevision).height;
docData.replicationRevision =
oldRevHeight + 1 + "-" + database.hashFunction(JSON.stringify(docData));
return docData;
}, false);
return database;
};

Use Effect doesn't run on websocket ON

I am working on a websocket project in react. But when I send a message, the websocket does reload to display new messages. I have to reload my page manually to show the changes.
Here's my use Effect Hook
useEffect(() => {
if (socket.current) {
socket.current.on('msgSent', ({ newMsg }) => {
console.log('MESSAGE SENT', newMsg)
if (newMsg.receiver === openChatId.current) {
setMessages((prev) => [...prev, newMsg])
setChats((prev) => {
const previousChat = prev.find(
(chat) => chat.messagesWith === newMsg.receiver
)
previousChat.lastMessage = newMsg.msg
previousChat.date = newMsg.date
return [...prev]
})
}
})
}
}, [])
When I remove the useEffect dependency (i.e []), It works but it renders the message multiple times on the screen.
Here's the rest of my frontend client code
const openChatId = useRef('')
const auth = useContext(AuthContext)
const queryMessage = new URLSearchParams(search).get('message')
useEffect(() => {
if (!socket.current) {
socket.current = io(process.env.REACT_APP_API)
}
if (socket.current) {
socket.current.emit('join', { userId: auth.user._id })
socket.current.on('connectedUsers', ({ users }) => {
users.length > 0 && setConnectedUsers(users)
})
}
if (chats.length > 0 && !queryMessage) {
history.push(`/messages?message=${chats[0].messagesWith}`, undefined, {
shallow: true,
})
}
return () => {
if (socket.current) {
socket.current.emit('logout')
socket.current.off()
}
}
}, [chats])
useEffect(() => {
const getAllChats = async (token) => {
try {
setLoading(true)
const res = await getChats(token)
if (res) {
setChats(res)
setLoading(false)
}
} catch (err) {
console.log(err)
setLoading(false)
}
}
getAllChats(auth.token)
}, [])
useEffect(() => {
const loadMessages = () => {
socket.current.emit('loadMessages', {
userId: auth.user._id,
messagesWith: queryMessage,
})
socket.current.on('messagesLoaded', async ({ chat }) => {
setMessages(chat.messages)
setBannerData({
firstName: chat.messagesWith.firstName,
lastName: chat.messagesWith.lastName,
profilePicUrl: chat.messagesWith.profilePicUrl,
})
openChatId.current = chat.messagesWith._id
})
socket.current.on('noChatFound', async () => {
const { firstName, lastName, profilePicUrl } = await ChatGetUserInfo(
queryMessage,
auth.token
)
setBannerData({ firstName, lastName, profilePicUrl })
setMessages([])
openChatId.current = queryMessage
})
}
if (socket.current) {
loadMessages()
}
}, [queryMessage])
const sendMsg = (msg) => {
if (socket.current) {
socket.current.emit('sendNewMsg', {
userId: auth.user._id,
msgSendToUserId: openChatId.current,
msg,
})
}
}
The backend works very well. U think my problem is with the useEffect
I fixed it. I was missing the [chats] dependency

Firebase updating Documents delayed by one onClick event

Using react.js & firebase
The code below represents a simple button which increases/decreases +1/-1 whenever its clicked. It also updates one of the documents on the backend (using firebase). Everything seems to work fine on the surface but not on firebase. When you click on the button, it'll show +1 on the UI and console.log but not on firebase. In other words when plusCount state is at 0, it shows +1 on firebase and when plusCount state is at +1, it shows 0 on firebase. How can I fix this to make sure it shows the same number on the frontend and the backend? I also added the useFirestore hook component below, there may be a mistake that I'm unaware of in there somewhere.
Thank you for any help.
Button component:
import React, { useState } from 'react';
import { useFirestore } from "../../hooks/useFirestore"
export default function Testing({ doc }) {
const { updateDocument } = useFirestore('projects')
const [plusActive, setPlusActive] = useState(false)
const [plusCount, setPlusCount] = useState(0)
function p() {
setPlusActive(prevState => !prevState);
plusActive ? setPlusCount(plusCount - 1) : setPlusCount(plusCount + 1)
}
const handlePlus = (e) => {
e.preventDefault();
p();
updateDocument(doc.id, {
votes: plusCount
})
}
console.log(plusCount)
return (
<div>
<button onClick={handlePlus}>like | {plusCount}</button>
</div>
)
}
useFirestore hook component:
import { projectFirestore, timestamp } from "../firebase/config"
let initialState = {
document: null,
isPending: false,
error: null,
success: null,
}
const firestoreReducer = (state, action) => {
switch (action.type) {
case 'IS_PENDING':
return { isPending: true, document: null, success: false, error: null }
case 'ADDED_DOCUMENT':
return { isPending: false, document: action.payload, success: true, error: null }
case 'DELETED_DOCUMENT':
return { isPending: false, document: null, success: true, error: null }
case 'ERROR':
return { isPending: false, document: null, success: false, error: action.payload }
case "UPDATED_DOCUMENT":
return { isPending: false, document: action.payload, success: true, error: null }
default:
return state
}
}
export const useFirestore = (collection) => {
const [response, dispatch] = useReducer(firestoreReducer, initialState)
const [isCancelled, setIsCancelled] = useState(false)
// collection ref
const ref = projectFirestore.collection(collection)
// only dispatch if not cancelled
const dispatchIfNotCancelled = (action) => {
if (!isCancelled) {
dispatch(action)
}
}
// add a document
const addDocument = async (doc) => {
dispatch({ type: 'IS_PENDING' })
try {
const createdAt = timestamp.fromDate(new Date())
const addedDocument = await ref.add({ ...doc, createdAt })
dispatchIfNotCancelled({ type: 'ADDED_DOCUMENT', payload: addedDocument })
}
catch (err) {
dispatchIfNotCancelled({ type: 'ERROR', payload: err.message })
}
}
// delete a document
const deleteDocument = async (id) => {
dispatch({ type: 'IS_PENDING' })
try {
await ref.doc(id).delete()
dispatchIfNotCancelled({ type: 'DELETED_DOCUMENT' })
}
catch (err) {
dispatchIfNotCancelled({ type: 'ERROR', payload: 'could not delete' })
}
}
// update a document
const updateDocument = async (id, updates) => {
dispatch({ type: "IS_PENDING" })
try {
const updatedDocument = await ref.doc(id).update(updates)
dispatchIfNotCancelled({ type: "UPDATED_DOCUMENT", payload: updatedDocument })
return updatedDocument
}
catch (error) {
dispatchIfNotCancelled({ type: "ERROR", payload: error })
return null
}
}
useEffect(() => {
return () => setIsCancelled(true)
}, [])
return { addDocument, deleteDocument, updateDocument, response }
}```
For your use-case, you should useEffect() to listen the changes for plusCount. See code below:
useEffect(() => {
updateDocument('test', {
votes: plusCount
})
}, [plusCount]);
const handlePlus = (e) => {
e.preventDefault();
setPlusActive(prevState => !prevState);
plusActive ? setPlusCount(plusCount - 1) : setPlusCount(plusCount + 1)
}
Everytime you click the button it will listen to the changes of plusCount which then the updateDocument will also be triggered together with the updated state. See below screenshot for the result:
As you can see, the frontend and backend is now aligned.
You can find more information by checking out this documentation.

Create shareable ObjectURL from blob

So, I am creating a walkie talkie website\app but the problem is that when I record the audio and convert the bolb to objectUrl it works only in the sender's device. I did some research and found out that createObjectURL only works in local env. How do I send it.
Here is my index.js:
// index.js
import Head from 'next/head';
import { useEffect, useState } from 'react';
import style from '../../../styles/Talk.module.css';
import apiBaseUrl from '../../../components/apiBaseUrl';
const talk = ({ id }) => {
const [paused, setPaused] = useState(false);
const [copied, setCopied] = useState(false);
const [webScokect, setWebScokect] = useState();
const [participants, setParticipants] = useState(0);
const [userId, setUserId] = useState();
const [stream, setStream] = useState();
const [mediaRecorder, setMediaRecorder] = useState();
useEffect(() => {
const ws = new WebSocket(`ws://localhost:8080`);
setWebScokect(ws);
ws.onmessage = async (e) => {
const data = JSON.parse(e.data);
if (data.status === 'failure') {
return alert('technical error');
}
if (data.status === 'success') {
if (data.type === 'handShake') {
try {
const res = await fetch(
`${apiBaseUrl}/register?roomId=${id}&userId=${data.data.randomId}`
);
const mydata = await res.json();
if (mydata.status === 'failure') {
return alert('technical error');
}
setUserId(data.data.randomId);
setParticipants(mydata.data.participants);
} catch (error) {
return alert('technical error');
}
} else {
console.log(data.data.blob);
const audio = new Audio(data.data.blob);
audio.play();
}
}
};
}, []);
const sendBlobToServer = (audioUrl) => {
webScokect.send(
JSON.stringify({
roomId: id,
userId,
blob: audioUrl,
})
);
};
const handleClick = async () => {
if (paused) {
mediaRecorder.stop();
stream.getTracks().forEach(function (track) {
track.stop();
});
} else {
const userMedia = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const userRocrder = new MediaRecorder(userMedia);
userRocrder.start();
const audioChunks = [];
userRocrder.addEventListener('dataavailable', (event) => {
audioChunks.push(event.data);
});
userRocrder.addEventListener('stop', () => {
const audioBlob = new Blob(audioChunks);
const audioUrl = URL.createObjectURL(audioBlob);
sendBlobToServer(audioUrl);
});
setStream(userMedia);
setMediaRecorder(userRocrder);
}
setPaused(!paused);
};
const handleCopy = () => {
navigator.clipboard.writeText(`http://localhost:3000/talk/${id}`);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 1500);
};
return (
<div className={style.container}>
<Head>
<title>In room: {id}</title>
</Head>
<img
src="/walkietalkie-talk.png"
alt="walkie-talk"
className={style.walkieTalkieImage}
onClick={handleClick}
/>
<img
src="/record.png"
alt="record"
className={`${style.record} ${paused && style.show}`}
/>
<p className={style.getInviteLink} onClick={handleCopy}>
{copied ? 'Copied' : 'Copy invite link'}
</p>
<p className={style.memberCount}>{participants} members in room</p>
</div>
);
};
export async function getServerSideProps(context) {
const { id } = context.params;
return {
props: { id },
};
}
export default talk;
And app.js ws code:
// app.js
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws, req) => {
const randomId = v4().substring(0, 15);
ws.id = randomId;
ws.send(
JSON.stringify({
status: 'success',
type: 'handShake',
data: {
randomId,
},
})
);
ws.on('message', (data) => {
try {
const jsonData = JSON.parse(data);
if (!jsonData.roomId || !jsonData.blob || !jsonData.userId) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
if (
typeof jsonData.roomId !== 'string' ||
typeof jsonData.userId !== 'string' ||
typeof jsonData.blob !== 'string'
) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
Room.findOne({ roomId: jsonData.roomId }, (err, result) => {
if (err) {
console.log(err);
} else {
if (!result) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
if (!result.users.includes(jsonData.userId)) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
wss.clients.forEach(function each(client) {
if (
client.id !== jsonData.userId &&
result.users.includes(client.id)
) {
client.send(
JSON.stringify({
status: 'success',
type: 'message',
data: {
blob: jsonData.blob,
},
})
);
}
});
}
});
} catch {
ws.send(
JSON.stringify({
status: 'failure',
})
);
}
});
});

How can I pull gmail data with Vue.js

I'm essentially trying to create an application for myself that I can manage my emails etc. with Vue.js
I've managed to get authorisation working using an npm package called vue-googleapis
However I am now trying to pull data from my (or the users) gmail account but running into some errors.
Here's my existing code in my component:
<div class="gmail-init">
<h1>Google APIs example - oAuth2 (vuex)</h1>
<p>isReady: {{ gauthReady }}</p>
<p>isSignedIn: {{ isSignedIn }}</p>
<p v-if="isSignedIn && user">{{ user.getBasicProfile().getName() }}</p>
<button :disabled="isSignedIn || !gauthReady" #click="signIn">Sign In</button>
<button :disabled="!isSignedIn || !gauthReady" #click="signOut">Sign Out</button>
<button :disabled="!isSignedIn || !gauthReady" #click="disconnect">Disconnect</button>
<button :disabled="!isSignedIn || !gauthReady" #click="labels">Labels</button>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
name: 'GmailInit',
computed: {
...mapGetters('gauth', {
gauthReady: 'isReady',
isSignedIn: 'isSignedIn',
user: 'getUser'
})
},
mounted () {
this.$store.dispatch('gauth/init')
},
methods: {
...mapActions('gauth', {
signIn: 'signIn',
signOut: 'signOut',
disconnect: 'disconnect'
}),
async labels () {
console.log('labels called')
const auth = this.isSignedIn
// const response = await this.$google.api.client.youtube.playlists.list({
const gmail = this.$google.gmail({ version: 'v1', auth })
const response = await gmail.users.labels.list({
// mine: true
userId: 'me'
// part: "snippet",
})
const labels = response.data.labels
if (labels.length) {
console.log(response.result.items)
labels.forEach((label) => {
console.log(`- ${label.name}`)
})
// this.playlistItems = response.result.items
} else {
console.log('error')
}
}
}
}
</script>
and here's my code for the import (vuex/store)
const STATUS_LOADING = 'loading'
const STATUS_READY = 'ready'
export default {
namespaced: true,
state: {
status: STATUS_LOADING,
signedId: null,
user: null,
error: null
},
mutations: {
setStatus (state, status) {
state.status = status
},
setSignedIn (state, signedId) {
state.signedId = signedId
},
setError (state, error) {
state.error = error
},
setUser (state, user) {
state.user = user
}
},
actions: {
init (context) {
const google = this._vm.$google
const load = setInterval(function () {
if (google.isInit) {
context.commit('setStatus', STATUS_READY)
context.commit(
'setSignedIn',
google.api.auth2.getAuthInstance().isSignedIn.get()
)
google.api.auth2.getAuthInstance().isSignedIn.listen(function (signedId) {
context.commit('setSignedIn', signedId)
})
google.api.auth2.getAuthInstance().currentUser.listen(function (user) {
context.commit('setUser', user)
})
clearInterval(load)
}
})
},
async signIn (context) {
try {
await this._vm.$google.api.auth2.getAuthInstance().signIn()
} catch (e) {
console.error(e)
context.commit('setError', e.error)
}
},
async signOut (context) {
try {
await this._vm.$google.api.auth2.getAuthInstance().signOut()
} catch (e) {
console.error(e)
context.commit('setError', e.error)
}
},
async disconnect (context) {
try {
await this._vm.$google.api.auth2.getAuthInstance().disconnect()
} catch (e) {
console.error(e)
context.commit('setError', e.error)
}
}
},
getters: {
isReady (state) {
return state.status === STATUS_READY
},
isSignedIn (state) {
return state.signedId === true
},
getUser (state) {
return state.user
}
}
}
the main function that isn't working:
async labels () {
console.log('labels called')
const auth = this.isSignedIn
// const response = await this.$google.api.client.youtube.playlists.list({
const gmail = this.$google.gmail({ version: 'v1', auth })
const response = await gmail.users.labels.list({
// mine: true
userId: 'me'
// part: "snippet",
})
const labels = response.data.labels
if (labels.length) {
console.log(response.result.items)
labels.forEach((label) => {
console.log(`- ${label.name}`)
})
// this.playlistItems = response.result.items
} else {
console.log('error')
}
}

Categories