This is my typescript function where I'm trying to use a promise:
public onEditSubmit() {
const model = this._sharedService.createUpdateModel(
null,
this.editForm
) as LOG;
model.fileId = this.fileId;
model.startEffectiveDate = Shared.toISODate(model.startEffectiveDate);
model.endEffectiveDate = Shared.toISODate(model.endEffectiveDate);
let deferredExecutionCheck = new Promise((resolve, reject) => {
this._updateService
.getAllById(this.selectedItem.LogId)
.subscribe(
r => {
this.records = r;
this.records.forEach(element => {
if (
element.StatusId === 1 ||
element.StatusId === 2 ||
element.StatusId === 4 ||
element.StatusId === 5
) {
this._notificationService.showErrorMessage(
`MESSAGE GOES HERE`,
"IN PROGRESS"
);
reject("In Progress");
}
});
resolve("Not In Progress");
},
e => {
throw e;
}
);
console.log("finished");
});
let originalEditSubmit = function(result: any) {
if (this.editMode === "Add") {
this.add(model);
} else {
if (
(model.wfStatusId === Status.Review ||
model.wfStatusId === Status.LoadFailed ||
model.wfStatusId === Status.Completed) &&
model.eventStatusId === eStatus.Cancelled
) {
this._confirmDlg.closable = false;
this._confSvc.confirm({
accept: () => {
model.cancelRcdb = true;
this.update(model);
},
message: "Cancel RCdB Dataset?",
reject: () => {
model.cancelRcdb = false;
this.update(model);
}
});
} else {
this.update(model);
}
}
};
deferredExecutionCheck.then(
result => originalEditSubmit(result),
error => console.log("error", error)
);
}
Error: Uncaught (in promise): TypeError: Cannot read property
'editMode' of undefined TypeError: Cannot read property 'editMode' of
undefined at originalEditSubmit
I moved the this.fileId property outside of the originalEditSumbmit method and it now is being read. But now it seems like this.editMode is now having the same issue.
Can I not have these properties inside of my promises like this?
change
let originalEditSubmit = function(result: any) {
to
let originalEditSubmit = (result: any) => {
Related
I have a simple employee profile generator app. Everything works just as expected up until the promise for generatePage(employeeData). The console correctly logs employeeData but it is not getting passed to generatePage. Does anyone have insight into why? I have also included a picture of the beginning code for generate-page.js and the "undefined" console error message.
const {writeFile, copyFile} = require('./utils/generate-site.js');
const generatePage = require('./src/page-template.js');
const mockData = [
{
// lots of mock data objects here
},
]
let employeeData = mockData;
function init() {
return inquirer.prompt(questions.startQuestions);
}
function getEmployeeData(answers) {
if (answers.role === 'Engineer') {
let engineer = new Engineer (
answers.name,
answers.id,
answers.email,
answers.role
)
return getEngineerData(engineer);
} else if (answers.role === 'Intern') {
let intern = new Intern (
answers.name,
answers.id,
answers.email,
answers.role
)
return getInternData(intern)
} else if (answers.role === 'Manager') {
let manager = new Manager (
answers.name,
answers.id,
answers.email,
answers.role
)
return getManagerData(manager)
}
}
function getEngineerData(engineer) {
return new Promise((resolve) => {
resolve (
inquirer.prompt(questions.engineerQuestions)
.then ((response) => {
engineer = {...engineer, ...response};
// console.log(engineer)
employeeData.push(engineer)
}
)
)
})
}
function getInternData(intern) {
return new Promise((resolve) => {
// same as getEngineerData function
})
}
function getManagerData(manager) {
return new Promise((resolve) => {
// same as getEngineerData function
})
}
function confirm() {
return inquirer.prompt(questions.confirmQuestion)
}
function buildTeam() {
init()
.then(answers => getEmployeeData(answers))
.then(confirm)
.then(response => response.confirmAdd ? buildTeam() : console.log(employeeData))
.then(employeeData => generatePage(employeeData))
.then(pageHTML => {
return writeFile(pageHTML)
})
.then (writeFileResponse => {
console.log(writeFileResponse);
return copyFile()
})
.then(copyFileResponse => {
console.log(copyFileResponse);
})
.catch (err => {
console.log(err);
});
}
buildTeam();
console.log returns "undefined" so the solution was to return the employeeData array in the promise chain to pass on.
.then(response => {
if (response.confirmAdd) {
buildTeam()
return employeeData
} else {
return employeeData
}
})
This is the code I use to create a Google Client wrapper
var googleAuth = (function () {
function installClient () {
var apiUrl = 'https://apis.google.com/js/api.js'
return new Promise((resolve) => {
var script = document.createElement('script')
script.src = apiUrl
script.onreadystatechange = script.onload = function () {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
setTimeout(function () {
resolve()
}, 500)
}
}
document.getElementsByTagName('head')[0].appendChild(script)
})
}
function initClient (config) {
return new Promise((resolve) => {
window.gapi.load('auth2', () => {
window.gapi.auth2.init(config)
.then(() => {
resolve(window.gapi)
})
})
})
}
function Auth () {
if (!(this instanceof Auth))
return new Auth()
this.GoogleAuth = null /* window.gapi.auth2.getAuthInstance() */
this.isAuthorized = false
this.isInit = false
this.prompt = null
this.isLoaded = function () {
/* eslint-disable */
console.warn('isLoaded() will be deprecated. You can use "this.$gAuth.isInit"')
return !!this.GoogleAuth
}
this.load = (config, prompt) => {
installClient()
.then(() => {
return initClient(config)
})
.then((gapi) => {
this.GoogleAuth = gapi.auth2.getAuthInstance()
this.isInit = true
this.prompt = prompt
this.isAuthorized = this.GoogleAuth.isSignedIn.get()
})
}
this.signIn = (successCallback, errorCallback) => {
return new Promise((resolve, reject) => {
if (!this.GoogleAuth) {
if (typeof errorCallback === 'function') errorCallback(false)
reject(false)
return
}
this.GoogleAuth.signIn()
.then(googleUser => {
if (typeof successCallback === 'function') successCallback(googleUser)
this.isAuthorized = this.GoogleAuth.isSignedIn.get()
resolve(googleUser)
})
.catch(error => {
if (typeof errorCallback === 'function') errorCallback(error)
reject(error)
})
})
}
this.getAuthCode = (successCallback, errorCallback) => {
return new Promise((resolve, reject) => {
if (!this.GoogleAuth) {
if (typeof errorCallback === 'function') errorCallback(false)
reject(false)
return
}
this.GoogleAuth.grantOfflineAccess({ prompt: this.prompt })
.then(function (resp) {
if (typeof successCallback === 'function') successCallback(resp.code)
resolve(resp.code)
})
.catch(function (error) {
if (typeof errorCallback === 'function') errorCallback(error)
reject(error)
})
})
}
this.signOut = (successCallback, errorCallback) => {
return new Promise((resolve, reject) => {
if (!this.GoogleAuth) {
if (typeof errorCallback === 'function') errorCallback(false)
reject(false)
return
}
this.GoogleAuth.signOut()
.then(() => {
if (typeof successCallback === 'function') successCallback()
this.isAuthorized = false
resolve(true)
})
.catch(error => {
if (typeof errorCallback === 'function') errorCallback(error)
reject(error)
})
})
}
}
return new Auth()
})()
function installGoogleAuthPlugin(Vue, options) {
//set config
let GoogleAuthConfig = null
let GoogleAuthDefaultConfig = { scope: 'profile email', discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'] }
let prompt = 'select_account'
if (typeof options === 'object') {
GoogleAuthConfig = Object.assign(GoogleAuthDefaultConfig, options)
if (options.scope) GoogleAuthConfig.scope = options.scope
if (options.prompt) prompt = options.prompt
if (!options.clientId) {
console.warn('clientId is required')
}
} else {
console.warn('invalid option type. Object type accepted only')
}
//Install Vue plugin
Vue.gAuth = googleAuth
Object.defineProperties(Vue.prototype, {
$gAuth: {
get: function () {
return Vue.gAuth
}
}
})
Vue.gAuth.load(GoogleAuthConfig, prompt)
}
export default installGoogleAuthPlugin
And in main.js I used it as follows:
import GoogleAuth from './auth/goauthWrapper.js'
const gauthOption = {
clientId: 'XXXXXXXX.apps.googleusercontent.com',
scope: 'profile email',
prompt: 'select_account'
}
Vue.use(GoogleAuth, gauthOption)
I'm able to access this.$gAuth.signIn() & this.$gAuth.signOut() however, when I try to access this.$gAuth.isAuthorized it is always false. Even after successful sign in, the value always false
I printed out this.$gAuth on Vue created() and get the following:
Auth object is this before sign in
Auth object is this after sign in (but I have to manually refresh the page!):
I wonder why I'm unable to access the this.$gAuth.isAuthorized when it's true?
Do I need to do a bind? How would I go about doing that? Thanks!
I was trying to build a PWA with the help of a service worker when it comes to caching, everything went smooth. But I ran into a curious problem. I could not serve my assets with SW when the app is offline. It seems that SW always fails to respond to a 'navigate' request.
Uncaught (in promise) TypeError: Failed to fetch
this.addEventListener('fetch', async event => {
event.respondWith(
(async function() {
const requestObj = event.request;
console.log(event);
const urlParts = requestObj.url.split('/');
const fileName = urlParts[urlParts.length - 1];
const fileExtension = fileName.split('.')[fileName.split('.').length - 1];
if (requestObj.method === 'GET') {
if (requestObj.mode === 'navigate' && event.request.headers.get('accept').includes('text/html')) {
console.log('Navigating', requestObj);
const urlParts = requestObj.url.split('/');
console.log(urlParts);
console.log('looking for another option...');
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
});
}
// If its an image, then save it if it is in '.png' format
if (fileExtension === 'jpg' || requestObj.destination === 'image') {
caches
.match(requestObj)
.then(res => {
if (!res) {
throw new TypeError('Bad response status');
} else {
return res;
}
})
.catch(() => {
fetch(requestObj).then(response => {
console.log(response);
if (response.ok || (response.type === 'opaque' && response.status === 0)) {
caches.open('v1').then(cache => {
cache.put(requestObj, response);
});
}
return response;
});
return fetch(requestObj);
});
}
///////////////////////
if (
requestObj.destination === 'script' ||
requestObj.destination === 'style' ||
requestObj.destination === 'font'
) {
caches
.match(requestObj)
.then(response => {
if (response) {
return response;
} else {
throw new TypeError('Bad response status');
}
})
.catch(() => {
fetch(requestObj).then(res => {
if (res.ok) {
caches.open('v1').then(cache => {
cache.put(requestObj, res);
});
}
return res.clone();
});
});
}
//////////////////////
}
return fetch(requestObj);
})()
);
});
I don't think you need the async function inside the fetch event handler, caches.match returns a promise so it is good enough to be the parameter for the respondWith method
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(function(response) {
const requestObj = event.request;
console.log(event);
const urlParts = requestObj.url.split('/');
const fileName = urlParts[urlParts.length - 1];
const fileExtension = fileName.split('.')[fileName.split('.').length - 1];
if (requestObj.method === 'GET') {
if (requestObj.mode === 'navigate' && event.request.headers.get('accept').includes('text/html')) {
console.log('Navigating', requestObj);
const urlParts = requestObj.url.split('/');
console.log(urlParts);
console.log('looking for another option...');
caches.match(requestObj).then(function(response) {
return response || fetch(event.request);
});
}
// If its an image, then save it if it is in '.png' format
if (fileExtension === 'jpg' || requestObj.destination === 'image') {
caches
.match(requestObj)
.then(res => {
if (!res) {
throw new TypeError('Bad response status');
} else {
return res;
}
})
.catch(() => {
fetch(requestObj).then(response => {
console.log(response);
if (response.ok || (response.type === 'opaque' && response.status === 0)) {
caches.open('v1').then(cache => {
cache.put(requestObj, response);
});
}
return response;
});
return fetch(requestObj);
});
}
///////////////////////
if (
requestObj.destination === 'script' ||
requestObj.destination === 'style' ||
requestObj.destination === 'font'
) {
caches
.match(requestObj)
.then(response => {
if (response) {
return response;
} else {
throw new TypeError('Bad response status');
}
})
.catch(() => {
fetch(requestObj).then(res => {
if (res.ok) {
caches.open('v1').then(cache => {
cache.put(requestObj, res);
});
}
return res.clone();
});
});
}
return fetch(requestObj);
}
})
)
});
I have the following function
churnModel = () => {
if (this.props.churnModel === undefined || this.props.churnModel.length === 0) {
return("N/A")
} else {
this.props.churnModel.map((churn) => {
if (churn === undefined || churn.length === 0) {
return("N/A")
} else {
return(churn.map((model) => {
this.service(model.scoreModelId)
}))
}
})
}
};
The this.service functions looks like this...
service(e) {
switch(e.toString().toLowerCase()) {
case "in":
return <span>in</span>
case "rpt_callr":
return <span>repeat</span>
default:
return <span>na</span>
}
}
I am expecting to display the result in here:
<div className="riskScore">{this.churnModel()}</div>
Nothing gets displayed, but when I put in logs, those get printed.
What is happening here?
you need to put return before this.props.churnModel.map.this.service(model.scoreModelId)
A function will return undefined if nothing is nothing is returned.
map() takes a callback and changes each element of array to return value of the that callback. If you don't return anything all elements will be undefined
You can also get rid of return before this.service(model.scoreModelId) by removing {}.Like this.
return(churn.map((model) => this.service(model.scoreModelId)))
Here is the code
churnModel = () => {
if (this.props.churnModel === undefined || this.props.churnModel.length === 0) {
return("N/A")
} else {
return this.props.churnModel.map((churn) => {
if (churn === undefined || churn.length === 0) {
return("N/A")
} else {
return(churn.map((model) => {
return this.service(model.scoreModelId)
}))
}
})
}
};
You have to use return statement in couple of lines:
churnModel = () => {
if (this.props.churnModel === undefined || this.props.churnModel.length === 0) {
return("N/A")
} else {
return this.props.churnModel.map((churn) => {
if (churn === undefined || churn.length === 0) {
return("N/A")
} else {
return(churn.map((model) => {
return this.service(model.scoreModelId)
}))
}
})
}
};
Why do you need return? It's because you're using curly braces.
I get this error when I search for 'andkk':
Unhandled Rejection (TypeError): res.map is not a function
here's my code:
state = {
ListBook: [],
SaveQuery: '',
}
SearchBook = (query) => {
if (query.trim() !== '') {
BooksAPI.search(query).then((res) => {
res.map(book => (this.props.allBooks.filter((b) => b.id === book.id).map(b => book.shelf = b.shelf)))
if (res && res.length) this.setState({
ListBook: res,
SaveQuery: query
})
if (res.error) this.setState({
ListBook: [],
SaveQuery: 'query'
})
})
} else {
this.setState({
ListBook: []
})
}
}
I found out how to solve it:
BooksAPI.search(query).then((res) => {
if (res && res.length) this.setState({ListBook: res, SaveQuery: query})
if (res.error) return res
res.map(book => (this.props.allBooks.filter((b) => b.id === book.id).map(b => book.shelf = b.shelf)))