I'm trying to make 'get_current_url' func with redux-saga Btw, I've been making chrome extension with react js. So, I gotta have to use chrome.tabs.query api to get current uri Here is my code
import { Action } from "redux";
import { call, fork, put, takeEvery, takeLatest } from "redux-saga/effects";
import { all } from "redux-saga/effects";
import { timeActions } from "./timeSlice";
function getUrlApi() {
const queryInfo = { active: true, currentWindow: true };
let currentUrl: string = '';
chrome.tabs.query(queryInfo, (tabs: chrome.tabs.Tab[]) => {
const id = tabs[0].id;
chrome.tabs.sendMessage(id || 0, "GET_URL", (res: any) => {
console.log(res); // ---> res.url will be receive data
currentUrl = res.url; // I wanna allocate this data to currentUrl and return but there is something kind of lexical problem
})
});
return currentUrl;
}
function* getUrl() {
try {
const test: string = yield getUrlApi(); // ---> always get undefined
// yield timeActions.getUrlSuccess();
} catch (err) {
yield put(timeActions.getUrlFail(err));
}
}
function* watchGetUrl() {
yield takeLatest(timeActions.getUrl, getUrl);
}
export function* timeSaga() {
yield all([fork(watchGetUrl)]);
}
As you can see, I am trying to allocate res.url data to currentUrl; But, there is something lexical problem. As a consequence, it always return undefined; How can i solve this problem. Thank you
The problem is that the chrome api functions are asynchronous, so you are returning from the function before they are processed.
The chrome api supports promises, which are much easier to handle with sagas, so I'd suggest to use those instead.
async function getUrlApi() {
const queryInfo = { active: true, currentWindow: true };
const tabs = await chrome.tabs.query(queryInfo);
const id = tabs[0].id;
const res = await chrome.tabs.sendMessage(id || 0, "GET_URL");
console.log(res);
return res.url;
}