I've got an ionic react app which fetches data from a rest API. When I bundle the ab with ionic server or on Android the app works fine.
When I run the same code on iOS I got a blank page. Some Versions before it worked on iOS as well. When I rebase my code the version 5 days ago now it doesn't work at all.
the code looks like this:
export default function PostsContainer() {
let {categoryid} = useParams<any>();
const [posts, setPosts] = useState<any[]>([]);
const [page, setPage] = useState<number>(1);
const [totPages, setTotPages] = useState<number>(1);
const [title, setTitle] = useState<string>("Recent posts");
const baseUrl = BASE_URL + "wp-json/wp/v2";
const [loadingPosts, setLoadingPosts] = useState<boolean>(false);
useEffect(() => {
async function loadPosts() {
setLoadingPosts(false)
let url = baseUrl + "/posts?status=publish&page=" + page;
if (categoryid !== undefined) {
url = url + "&categories=" + categoryid;
getCategoryName(categoryid);
}
const response = await fetch(url);
if (!response.ok) {
return;
}
const totalPages = await response.headers.get("x-wp-totalpages");
const postsTemp = await response.json();
setPosts(postsTemp);
setTotPages(Number(totalPages));
setLoadingPosts(true);
console.log(posts)
}
loadPosts();
}, [page, categoryid]);
function handleClickNextPage() {
setPage(page + 1);
}
async function getCategoryName(id: number) {
let url = baseUrl + "/categories/" + id;
const response = await fetch(url);
if (!response.ok) {
return;
}
const category = await response.json();
setTitle(category.name);
}
if (loadingPosts) {
return (
<IonPage>
<IonHeader translucent={true}>
</IonHeader>
<IonContent>
{page === 1 ? <Slider listOfPosts={posts}/> : <div/>}
<Posts
listOfPosts={posts}
totPages={totPages}
handleClickNextPage={handleClickNextPage}
pageNumber={page}
/>
</IonContent>
</IonPage>
);
} else {
return <IonLoading
isOpen={!loadingPosts}
message={ION_LOADING_DIALOG}
duration={ION_LOADING_DURATION}
/>
}
}
are there any settings belonging to the rest api? The call is to a URL with https. When I remove the useefect and only render a static page without content, it works fine.
At the End it was a CORS error on Endpoint. I had to allow cordova://localhost on Endpoint.
Related
We are trying web crawl and get contents from multiple pages. I am taking the advantage of async API with Promise ALL which can execute requests in parallel.
Is there a limitation on the number of contexts which can be opened parallel?
const fs = require('fs');
let browser;
const batch_size = 4; // control the number of async parallel calls
(async () => { // main function
let urls = [];
urls = fs.readFileSync('./resources/input_selenium_urls.csv').toString().split("\n");
browser = await chromium.launch();
let context_size = 0;
let processUrls = [];
let total_length = 0;
for (let i=0;i<urls.length;i++,total_length++) {
if ((context_size==batch_size)||(i==urls.length-1)){
await Promise.all(processUrls.map(x => getHTMLPageSource(x)));
context_size = 0;
processUrls = [];
} else {
processUrls.push(urls[i]);
context_size++;
}
}
await browser.close();
})();
async function getHTMLPageSource(url) {
const context = await browser.newContext();
const page = await context.newPage();
let response = {}
try {
await page.goto(url, { waitUntil: 'networkidle' });
response = {
url : url,
content: await page.title(),
error : null
}
console.log(response);
}
catch {
response = {
error : "Timeout error"
}
}
context.close;
return response;
}
Browser contexts are cheap to create, but it's not clear whether there is a hard-coded limit on them from the docs perhaps the limit might depend on the browser you chose and your OS resources. I think you might only be able to find out by creating a lot of contexts.
Is there some one who can really help here?
I can't get anything from sso.getGraphData in the office addin generated from Yeoman generator.
Here is my code in ssoauthhelper.js:
export async function getGraphData() {
try {
let bootstrapToken = await OfficeRuntime.auth.getAccessToken({ allowSignInPrompt: true });
let exchangeResponse = await sso.getGraphToken(bootstrapToken);
if (exchangeResponse.claims) {
// Microsoft Graph requires an additional form of authentication. Have the Office host
// get a new token using the Claims string, which tells AAD to prompt the user for all
// required forms of authentication.
let mfaBootstrapToken = await OfficeRuntime.auth.getAccessToken({ authChallenge: exchangeResponse.claims });
exchangeResponse = sso.getGraphToken(mfaBootstrapToken);
}
if (exchangeResponse.error) {
// AAD errors are returned to the client with HTTP code 200, so they do not trigger
// the catch block below.
documentHelper.writeDataToOfficeDocument("response");
handleAADErrors(exchangeResponse);
} else {
/*const response = await sso.makeGraphApiCall(exchangeResponse.access_token);
documentHelper.writeDataToOfficeDocument(response);*/
const _EndPoint = "/me/messages";
const _UrlParams = "?$select=receivedDateTime,subject,isRead&$orderby=receivedDateTime&$top=10";
const response = await sso.getGraphData(exchangeResponse.access_token, _EndPoint, _UrlParams);
documentHelper.writeDataToOfficeDocument(response);
sso.showMessage("Your data has been added to the document.");
}
} catch (exception) {
if (exception.code) {
if (sso.handleClientSideErrors(exception)) {
fallbackAuthHelper.dialogFallback();
}
} else {
sso.showMessage("EXCEPTION: " + JSON.stringify(exception));
}
}
}
the code in documentHelper.js:
function writeDataToExcel(result) {
/*return Excel.run(function (context) {
const sheet = context.workbook.worksheets.getActiveWorksheet();
let data = [];
let userProfileInfo = filterUserProfileInfo(result);
for (let i = 0; i < userProfileInfo.length; i++) {
if (userProfileInfo[i] !== null) {
let innerArray = [];
innerArray.push(userProfileInfo[i]);
data.push(innerArray);
}
}
const rangeAddress = `B5:B${5 + (data.length - 1)}`;
const range = sheet.getRange(rangeAddress);
range.values = data;
range.format.autofitColumns();
return context.sync();
});*/
return Excel.run(function (context) {
const sheet = context.workbook.worksheets.getActiveWorksheet();
const rangeHeadings = sheet.getRange("A1:D1");
rangeHeadings.valueTypes = [["ReceivedDateTime", "subject", "Read?", "ID"]];
const _Contents = result.value;
for (let i = 0; i < _Contents.length; i++) {
if (_Contents !== null) {
let _TempArr = [];
_TempArr.push(_Contents[i].receivedDateTime);
_TempArr.push(_Contents[i].subject);
_TempArr.push(_Contents[i].isRead);
_TempArr.push(_Contents[i].id);
let _Data = [];
_Data.push(_TempArr);
const _rangeaddress = `A${2 + i}:D${2 + i}`;
const _rangedata = sheet.getRange(_rangeaddress);
_rangedata.values = _Data;
}
}
rangeHeadings.format.autofitColumns();
return context.sync();
});
}
When i run the add-in, it does not proceed after GET/ auth? as shown in below image.
Here are my permission in the Azure APP Registration:
I can't understand what is really happening. When i click on the button in the sideloaded task pane, nothing is sent from the Graph API as shown in the command prompt image. I am really grateful, if someone could point out where the error is.
I have defined the scopes in my manifiest file as well.
Please help.
I tried to share data between Safari browser and standalone PWA on iPhone12 with iOS 14.3.
The information, that this should work are here: https://firt.dev/ios-14/
I#ve tried this: https://www.netguru.com/codestories/how-to-share-session-cookie-or-state-between-pwa-in-standalone-mode-and-safari-on-ios
Without success.
Are there any suggestions to running this? Or is it not possible ...
This is the code
const CACHE_NAME = "auth";
const TOKEN_KEY = "token";
const FAKE_TOKEN = "sRKWQu6hCJgR25lslcf5s12FFVau0ugi";
// Cache Storage was designed for caching
// network requests with service workers,
// mainly to make PWAs work offline.
// You can give it any value you want in this case.
const FAKE_ENDPOINT = "/fake-endpoint";
const saveToken = async (token: string) => {
try {
const cache = await caches.open(CACHE_NAME);
const responseBody = JSON.stringify({
[TOKEN_KEY]: token
});
const response = new Response(responseBody);
await cache.put(FAKE_ENDPOINT, response);
console.log("Token saved! 🎉");
} catch (error) {
// It's up to you how you resolve the error
console.log("saveToken error:", { error });
}
};
const getToken = async () => {
try {
const cache = await caches.open(CACHE_NAME);
const response = await cache.match(FAKE_ENDPOINT);
if (!response) {
return null;
}
const responseBody = await response.json();
return responseBody[TOKEN_KEY];
} catch (error) {
// Gotta catch 'em all
console.log("getToken error:", { error });
}
};
const displayCachedToken = async () => {
const cachedToken = await getToken();
console.log({ cachedToken });
};
// Uncomment the line below to save the fake token
// saveToken(FAKE_TOKEN);
displayCachedToken();
Without success means no result, i've tried to set data in safari and get them in standalone pwa
I would like to run a Lighthouse audit programatically. I have found multiple examples on how to accomplish this with Puppeteer. However, is there a way to run a Lighthouse audit using the Chrome DevTools Protocol?
You can run Lighthouse programatically by using the PageSpeed Insights API: https://developers.google.com/speed/docs/insights/v5/about
Javascript example:
function run() {
const url = setUpQuery();
fetch(url)
.then(response => response.json())
.then(json => {
// See https://developers.google.com/speed/docs/insights/v5/reference/pagespeedapi/runpagespeed#response
// to learn more about each of the properties in the response object.
showInitialContent(json.id);
const cruxMetrics = {
"First Contentful Paint": json.loadingExperience.metrics.FIRST_CONTENTFUL_PAINT_MS.category,
"First Input Delay": json.loadingExperience.metrics.FIRST_INPUT_DELAY_MS.category
};
showCruxContent(cruxMetrics);
const lighthouse = json.lighthouseResult;
const lighthouseMetrics = {
'First Contentful Paint': lighthouse.audits['first-contentful-paint'].displayValue,
'Speed Index': lighthouse.audits['speed-index'].displayValue,
'Time To Interactive': lighthouse.audits['interactive'].displayValue,
'First Meaningful Paint': lighthouse.audits['first-meaningful-paint'].displayValue,
'First CPU Idle': lighthouse.audits['first-cpu-idle'].displayValue,
'Estimated Input Latency': lighthouse.audits['estimated-input-latency'].displayValue
};
showLighthouseContent(lighthouseMetrics);
});
}
function setUpQuery() {
const api = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed';
const parameters = {
url: encodeURIComponent('https://developers.google.com')
};
let query = `${api}?`;
for (key in parameters) {
query += `${key}=${parameters[key]}`;
}
return query;
}
function showInitialContent(id) {
document.body.innerHTML = '';
const title = document.createElement('h1');
title.textContent = 'PageSpeed Insights API Demo';
document.body.appendChild(title);
const page = document.createElement('p');
page.textContent = `Page tested: ${id}`;
document.body.appendChild(page);
}
function showCruxContent(cruxMetrics) {
const cruxHeader = document.createElement('h2');
cruxHeader.textContent = "Chrome User Experience Report Results";
document.body.appendChild(cruxHeader);
for (key in cruxMetrics) {
const p = document.createElement('p');
p.textContent = `${key}: ${cruxMetrics[key]}`;
document.body.appendChild(p);
}
}
function showLighthouseContent(lighthouseMetrics) {
const lighthouseHeader = document.createElement('h2');
lighthouseHeader.textContent = "Lighthouse Results";
document.body.appendChild(lighthouseHeader);
for (key in lighthouseMetrics) {
const p = document.createElement('p');
p.textContent = `${key}: ${lighthouseMetrics[key]}`;
document.body.appendChild(p);
}
}
run();
Source: https://developers.google.com/speed/docs/insights/v5/get-started
I'm developing an app in Nativescript for the first time and running into an issue where AJAX calls work on Android but not iOS. I have a login.js file which requires a user-view-model (user-view-model.js), and when I test the code on Android it takes me to the "home" page but it hits the catch function on iOS.
login.js:
var dialogsModule = require("ui/dialogs");
var UserViewModel = require("../../shared/view-models/user-view-model");
var applicationSettings = require("application-settings");
var user = new UserViewModel({
email: "aaa#aaa.com",
password: "aaa"
});
var frameModule = require("ui/frame");
var page;
exports.loaded = function(args) {
page = args.object;
page.bindingContext = user;
};
exports.login = function () {
user.login().catch(function(error) {
dialogsModule.alert({
message: "Unfortunately we could not find your account.",
okButtonText: "OK"
});
return Promise.reject();
}).then(function(response) {
console.dir(response)
console.log("past response")
applicationSettings.setString("user_id", response.user_id);
applicationSettings.setString("first_name", response.first_name);
applicationSettings.setString("last_name", response.last_name);
applicationSettings.setString("user_type", response.user_type);
var topmost = frameModule.topmost();
topmost.navigate("views/home/home");
});
};
user-view-model.js:
var config = require("../../shared/config");
var fetchModule = require("fetch");
var observableModule = require("data/observable");
var http = require("http");
function User(info) {
info = info || {};
var viewModel = new observableModule.fromObject({
email: info.email || "",
password: info.password || ""
});
viewModel.login = function() {
let loginEmail = JSON.stringify(this.get("email")).replace(/['"]+/g, '');
let loginPassword = JSON.stringify(this.get("password")).replace(/['"]+/g, '');
console.log(loginEmail, loginPassword);
let loginUrl = config.serverPHPServiceUrl + "Login.php?user_id=" + loginEmail + "&password=" + loginPassword;
console.log(loginUrl);
// I tried this way first and wasn't able to login on iOS, which made me try the second method below.
// return fetchModule.fetch(loginUrl, {
// method: "POST",
// headers: {
// "Content-Type": "application/json"
// }
// }).then(handleErrors).then(function(response) {
// return response.json();
// }).then(function(data) {
// console.dir(data);
// console.log(data["results"][0]["user_id"])
// return data["results"][0];
// });
// This method works on Android but not iOS.
return http.getJSON(loginUrl).then(function(response) {
console.dir(response);
return response.results[0];
})
};
return viewModel;
};
function handleErrors(response) {
console.log("in errors")
if (!response.ok) {
console.log(JSON.stringify(response));
throw Error(response.statusText);
}
return response;
}
module.exports = User;
Is there anything fundamentally wrong with my code, or do asynchronous calls work differently on iOS vs Android in Nativescript? I did the Grocery tutorial and didn't run into this issue, so I didn't think this was the case. Does it matter that the backend is using PHP?
I fixed my issue: I started a new project with Angular 2 and ran into the same error, but then it gave me the error message "Error: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." I solved it by adding "https" to my url call, but this post has another solution.