Axios: Previous response data being assigned to variable - javascript

I am creating a frontend to a patient booking system with Vue.js, which is simply a dynamic web form. The user first selects a type of treatment, then the practitioner they want to see, and finally the appointment time. All data is obtained via RESTful API calls using axios.
The available options in each form field are filtered using the previous choice. For example, the user will only be presented with the available times of their selected practitioner, and the practitioner can only be selected from the group of practitioners who can perform the chosen treatment.
Filtering the practitioners based on the selected treatment works just fine.
However, filtering the appointments based on the selected practitioner does not work -- it's out of sync: the appointments are loaded for the previously selected practitioner. I have checked the backend, which is fine, and the API calls are in-sync (i.e. the person_id matches the id of the newly selected practitioner).
What is causing this problem and how do I fix it?
Here is the Vue.js code that performs this filtering:
var app = new Vue({
el: '#app',
data: {
appointments: [],
practitionerId: 0,
practitioners: [],
treatmentId: 0,
treatments: [],
},
mounted: function () {
axios.get('/api/treatments')
.then(response => this.treatments = response.data);
},
watch: {
// filter available practitioners by the selected treatment
treatmentId: function () {
// get the allowed role ids for the selected treatment
var allowedRoleIds = '';
const allowedRoles = this.treatments[this.treatmentId - 1]['allowed_roles'];
for (var i = 0; i < allowedRoles.length; i++) {
allowedRoleIds += allowedRoles[i]['id'];
if (i + 1 < allowedRoles.length) {
allowedRoleIds += ',';
}
}
// load the practitioners using the allowed role ids
axios.get('/api/people?role_ids=' + allowedRoleIds)
.then(response => this.practitioners = response.data);
},
// filter the available appointments by the selected practitioner
practitionerId: function () {
axios.get('/api/appointments?person_id=' + this.practitionerId)
// ERROR!!! This is out of sync.
.then(response => this.appointments = response.data);
}
}
});

The problem can be resolved by adding a watcher to the appointments variable.
All I needed to do was add the following code within watch: { ... }:
appointments: function () {
// now it works -- even without any function body
}
This seems really odd to me. I should not need to create a watcher for a variable in order to have that variable updated in the function body of another watcher.
I have either missed something in the Vue.js documentation about watchers or this is a bug. If someone can shed some light on this in the comments that would be great!

You need to refresh practitionerId after fetching people from RESTful API.
For example, in treatmentId watch:
axios.get('/api/people?role_ids=' + allowedRoleIds).then(response => {
this.practitioners = response.data;
// refresh practitionerId whenever fetch new people
const selectedPractitionerId = this.practitionerId;
this.practitionerId = 0;
// if selected practitioner exists in new people
practitioners.forEach(p => {
if (p.id == selectedPractitionerId) {
this.practitionerId = p.id;
}
}) // you can omit this search if you force the user to select new practitioner whenever they change treatment
});

Related

How to use firebase onSnapshot in chain using JavaScript?

I want to use firebase's onSnapshot function sequentially. A situation where I want to apply this is given below.
Scenario:
There are 2 collections in firestore. Employees and Projects. In the Employees collection, the docs are storing the details of employees. And it also stores the IDs of Projects docs on which that particular employee is working. In Projects collection, the detail of projects is stored.
Goal:
First, I have to fetch the data from Employees collection related to a specific employee. Then, from the fetched employee data, I will have the project IDs on which he/she is working on. So, from that ID I need to fetch the project details. So, when any information related to project or employee changes, the data on screen should also change in real-time.
Issue:
I tried to write a nested code. But it works realtime only for employee data. It doesn't change when the project detail is updated. Something like this...
admin.auth().onAuthStateChanged(async () => {
if (check_field(admin.auth().currentUser)) {
await db.collection('Employees').doc(admin.auth().currentUser.uid).onSnapshot(snap => {
...
let project_details = new Promise(resolve => {
let projects = [];
for (let i in snap.data().projects_list) {
db.collection('Projects').doc(snap.data().projects_list[i]).onSnapshot(prj_snap => {
let obj = prj_snap.data();
obj['doc_id'] = prj_snap.id;
projects.push(obj);
});
}
resolve(projects);
});
Promise.all([project_details]).then(items => {
...
// UI updation
});
...
});
}
});
What is the correct way for doing this?
You're actually proposing a pretty complex dataflow scenario. I would approach this as a multi-step problem. Your goal is essentially:
If there is a user, listen in realtime for the list of project ids for that user.
For each project id, listen in realtime for details about that project.
(presumably) Clean up listeners that are no longer relevant.
So I would tackle it something like this:
let uid;
let employeeUnsub;
let projectIds = [];
let projectUnsubs = {};
let projectData = {};
const employeesRef = firebase.firestore().collection('Employees');
const projectsRef = firebase.firestore().collection('Projects');
firebase.auth().onAuthStateChanged(user => {
// if there is already a listener but the user signs out or changes, unsubscribe
if (employeeUnsub && (!user || user.uid !== uid)) {
employeeUnsub();
}
if (user) {
uid = user.uid;
// subscribe to the employee data and trigger a listener update on changes
employeeUnsub = employeesRef.doc(uid).onSnapshot(snap => {
projectIds = snap.get('projects_list');
updateProjectListeners();
});
}
});
function updateProjectListeners() {
// get a list of existing projects being listened already
let existingListeners = Object.keys(projectUnsubs);
for (const pid of existingListeners) {
// unsubscribe and remove the listener/data if no longer in the list
if (!projectIds.includes(pid)) {
projectUnsubs[pid]();
delete projectUnsubs[pid];
delete projectData[pid];
render();
}
}
for (const pid of projectIds) {
// if we're already listening, nothing to do so skip ahead
if (projectUnsubs[pid]) { continue; }
// subscribe to project data and trigger a render on change
projectUnsubs[pid] = projectsRef.doc(pid).onSnapshot(snap => {
projectData[pid] = snap.data);
render();
});
}
}
function render() {
const out = "<ul>\n";
for (const pid of projectIds) {
if (!projectData[pid]) {
out += `<li class="loading">Loading...</li>\n`;
} else {
const project = projectData[pid];
out += `<li>${project.name}</li>`;
}
}
out += "</ul>\n";
}
The above code does what you're talking about (and in this case the render() function just returns a string but you could do whatever you want to actually manipulate DOM / display data there).
It's a lengthy example, but you're talking about a pretty sophisticated concept of essentially joining realtime data dynamically as it changes. Hope this gives you some guidance on a way forward!

How to rerender Fullcalendar events

I've been trying for days to filter my fullcalendar and it still doesn't work properly. I've managed now at least to have 2 different calendars based on the page you are on (homepage or a different one with different events). So on the second one I have 2 dropdowns with lists. I've managed to pick the id of the selected item from the dropdown and I'm trying to give it as a parameter to my axios function so that the fullcalendar events has the json that I want. However if you change the type of the event (I have location as a type) then it doesn't update the change. So basically it initializes fine with the right events but if you have 2 types and want to change them from the dropdown it doens't do anything.
Here is the axios function:
events: async function () {
if (window.location.href.startsWith(window.origin + "/Booking")) {
var data = await axios.get("/Booking/GetBookingsFiltered/", {
params: {
locationIDparam: locationSelected(), // doesn't update when you change it
carIDparam: carSelected(),
}
})
//calendar.events = data.data; some things I've tried and don't work
//calendar.rerenderEvents();
//calendar.render();
return data.data;
} else {
var data = await axios.get("/Booking/GetBookingsByUser/") // this works
return data.data;
}
}
In case you need the code for how I get the parameters:
function locationSelected() {
var location = document.getElementById("location_filter");
var selected_location = location.options[location.selectedIndex].value;
console.log("You selected location: " + selected_location);
return selected_location;
//$("#calendar").fullCalendar('renderEvent');
//$('#calendar').fullCalendar('rerenderEvents');
}
function carSelected() {
var car = document.getElementById("car_filter");
var selected_car = car.options[car.selectedIndex].value;
console.log("You selected car: " + selected_car);
return selected_car;
}
I've tried using $("#calendar").fullCalendar('renderEvent');, $("#calendar").fullCalendar('rerenderEvent'); $("#calendar").fullCalendar().render(); idk nothing I find online or in the documentation of fullcalendar work....please help

Vue.js list not updating despite array change via assignment

I'm new to vue.js but I'm trying to display a list of options from an underlying array. However, when the underlying array is changed the list does not update/re-render. I am assigning the new array directly to the vue instance data value (not using splice or assigning via index) and in the console if I try and print out the underlying data (vm.clarifyings) that is updated, it is just the re-rendering that is not working. Even using vm.clarifyings.push(object) does not update the view in the browser.
Vue instance code:
var vm = new Vue({
delimiters: ['$[', '$]'], //change delimiters to allow django integration
el: '#vue_app',
data: {
title: init_info.title, //page title
active: 'presentations',
navClass: 'nav-item nav-link', //necessary for navbar rendering
features: features,
question: '',
response: '',
feature_id: init_info.opening,
last_feature: '',
clarif_id: '',
clarifyings: [],
show_clarifying: false,
},
Relevant method update:
fetch(url)
.then(response => response.json())
.then(function (data) {
// Type out question and response
typeWriter(data.question, 'question');
typeWriter(data.answer, 'response');
// Save selected option and disable previous selected option
option_disable(vm.last_feature);
vm.last_feature = option_ref;
// Show clarifying questions
vm.clarifyings = data.clarifyings;
if (vm.clarifyings.length){
vm.show_clarifying = true;
}
else {
vm.show_clarifying = false;
}
}
All of this executes normally it is simply the re-rendering that isn't working. If I specify the array when I initialize the Vue instance it renders properly it simply does not update.
HTML code:
<select class="selectpicker" data-live-search="true" v-model="clarif_id">
<option v-for="question in clarifyings">$[question.id$] - $[question.name$]</option>
</select>
Vuejs has a bad reactivity for arrays. See the official doc : https://v2.vuejs.org/v2/guide/reactivity.html#For-Arrays
Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
When you modify the length of the array, e.g. vm.items.length = newLength
You can use Vue.set(vm.clarifyings, indexOfItem, newValue) to overcome this problem. (Instead of vm.clarifyings.push(object))
The problem appeared to be a result of interference with bootstrap-selectpicker, it was fixed by using nextTick functionality in vue like so:
if (feature_asked) {
vm.clarifyings = data.clarifyings;
if (vm.clarifyings.length) {
vm.show_clarifying = true;
vm.$nextTick(function () {
$("#clarifying_qs").selectpicker("refresh");
});

Updating object with vue set doesnt change in html inside socketio listener

I have an chat app with vue for front where I listen for broadcasting from laravel.
I have data object for messages which I update with new messages when the chat is active.
Here is an update with used code:
data() {
return {
msg: '',
chatlist: JSON.parse(this.chatusers),
activeChats: [],
chatData: {},
openedChats: [],
maxOpened: Math.floor(window.innerWidth / 320),
}
},
methods: {
listener() {
Echo.private('user.' + window.uid)
.listen('Chat', (e) => {
//first if is for active and opened chats and here reactivity doesnt work
if (this.activeChats.includes(e.data.user.id) && this.openedChats.includes(e.data.user.id)) {
this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1 , e.data.message);
setTimeout(function() {
let chat = document.getElementById('chat-'+e.data.user.id);
chat.scrollTop = chat.scrollHeight;
}, 100);
//second if is for inactive chats and here reactivity works
}else if (!this.activeChats.includes(e.data.user.id)) {
axios.post('/messages', {
id: e.data.user.id
}).then((res) => {
this.chatData[e.data.user.id] = res.data;
this.activeChats.push(e.data.user.id);
setTimeout(function() {
let chat = document.getElementById('chat-'+e.data.user.id);
chat.scrollTop = chat.scrollHeight;
}, 100);
}).catch((err) => {
console.log(err);
});
//third if is for active chats that are not opened on page, so its same as first and it does not work
}else if(this.activeChats.includes(e.data.user.id) && !this.openedChats.includes(e.data.user.id) && this.openedChats.length < this.maxOpened) {
this.openedChats.push(e.data.user.id);
this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1, e.data.message);
}
});
}
}
I am calling listener in mounted.
The objects are changing but there is no reactivity on side that is receiving the message, so problem may be in echo listen, but since for second if statement is working I am not sure what can be a problem...
Seems like setting object property from echo listen does not trigger the change..
Update:
I tried this:
I opened chat on click which populated chatData[e.data.user.id] same as I use when I get new message and chat is not opened..
Then:
listener() {
Echo.private('user.' + window.uid)
.listen('Chat', (e) => {
this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1 , e.data.message);
});
}
I call this and it still did not work which means that if it does work out of laravel echo but not in, there must be a problem.
So I tried to look for problem and saw that objects are updating but not triggering the change.
I found stupid solution to add new variable as empty array that updates at same time and place where I update the object, like so:
this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1 , e.data.message);
this.array.push(1);
And then I used this array in v-for next to v-for that is using object.
That part is important so it triggers the change of object too, why I dont know but it works :D
Your issue is actually created by the second part of the code:
//second if is for inactive chats and here reactivity works
}else if (!this.activeChats.includes(e.data.user.id)) {
axios.post('/messages', {
id: e.data.user.id
}).then((res) => {
this.chatData[e.data.user.id] = res.data;
this.activeChats.push(e.data.user.id);
setTimeout(function() {
let chat = document.getElementById('chat-'+e.data.user.id);
chat.scrollTop = chat.scrollHeight;
}, 100);
}).catch((err) => {
console.log(err);
});
Mainly the line:
this.chatData[e.data.user.id] = res.data;
This is adding a new property to the this.chatData without passing it through a Vue.set, meaning that while you read it fine, any changes to this object are not tracked.
What's inside data that is supposed to be tracked? data.messages
Since this property is not tracked, any interaction with this won't result in the proper "reactivity", and requires
The fix for your problem is simple, make sure that new entries to the chatData structure are passed through the Vue set function:
this.$set(this.chatData, e.data.user.id, res.data);

How to collect and return aggregated data as an Array from a table in Protractor?

I am trying to aggregate a list of dates from a data table, written in Angular, in a Protractor test. I'm doing the aggregation from a PageObject class that is called in the Protractor test. I know that my code is successfully grabbing the text I want, but when I try to console.log the returned array, I get an empty array. I'm still new to Javascript/Typescript, Angular, and Protractor and this may be a result of my newness to the asynchronous nature of this development environment.
Code is as follows,
The PageObject SpecMapper class with method:
import { browser, element, by } from 'protractor';
export class SpecMapperPage {
getImportDateSubmittedColumnValues() {
let stringDatesArray: Array<string> = [];
// currently this css selector gets rows in both import and export tables
// TODO: get better identifiers on the import and export tables and columns
element.all(by.css('md-card-content tbody tr.ng-tns-c3-0')).each(function(row, index){
// check outerHTML for presence of "unclickable", the rows in the export table
row.getAttribute('outerHTML').then(function(outerHTML:string) {
// specifically look for rows without unclickable
if(outerHTML.indexOf("unclickable") < 0){
// grab the columns and get the third column, where the date submitted field is
// TODO: get better identifiers on the import and export columns
row.all(by.css("td.ng-tns-c3-0")).get(2).getText().then(function(text:string) {
stringDatesArray.push(text);
});
}
});
});
return stringDatesArray;
}
}
I know it's not the prettiest code, but it's temporary place holder while my devs make me better attributes/classes/ids to grab my variables. Key things to note is that I create a string Array to hold the values I consider relevant to be returned when the method is finished.
I used WebStorm and put a breakpoint at the stringDatesArray.push(text) and return stringDatesArray lines. The first line shows that the text variable has a string variable that I'm looking for and is successfully getting pushed. I see the success in debug mode as I can see the stringDatesArray and see the values in it. The second line though, the array return, shows that the local variable stringDatesArray is empty. This is echoed in the following code when I try to console.log the array:
The Protractor run Spec class with my test in it:
import { SpecMapperPage } from "./app.po";
import {browser, ExpectedConditions} from "protractor";
describe('spec mapper app', () => {
let page: SpecMapperPage;
let PROJECT_ID: string = '57';
let PROJECT_NAME: string = 'DO NOT DELETE - AUTOMATED TESTING PROJECT';
beforeEach(() => {
page = new SpecMapperPage();
});
describe('import/export page', () => {
it('verify sort order is desc', () => {
browser.waitForAngularEnabled(false);
// Step 1: Launch Map Data from Dashboard
page.navigateTo(PROJECT_ID);
browser.driver.sleep(5000).then(() => {
// Verify: Mapping Screen displays
// Verify on the specmapper page by checking the breadcrumbs
expect(page.getProjectNameBreadCrumbText()).toContain(PROJECT_NAME);
expect(page.getProjectMapperBreadCrumbText()).toEqual("MAPPER");
// Verify: Verify Latest Submitted Date is displayed at the top
// Verify: Verify the Submitted Date column is in descending order
console.log(page.getImportDateSubmittedColumnValues());
});
});
});
});
I acknowledge that this code is not actively using the niceties of Protractor, there's a known issue with our app that will not be addressed for a couple of months, so I am accessing the driver directly 99% of the time.
You'll note that I call the method I posted above as the very last line in the browser.driver.sleep().then() clause, page.getImportDateSubmittedColumnValues().
I thought maybe I was running into asynchronous issues with the call being done before the page was loaded, thus I put it in the .then() clause; but learned with debugging that was not the case. This code should work once I have the array returning properly though.
The console.log is printing an empty [] array. That is synonymous with the results I saw when debugging the above method directly in the PageObject SpecMapper class. I wish to do some verification that the strings are returned properly formatted, and then I'm going to do some date order comparisons. I feel like returning an array of data retrieved from a page is not an unusual request, but I can't seem to find a good way to Google what I'm trying to do.
My apologies if I am hitting some very obvious roadblock, I'm still learning the nuances of Typescript/Angular/Protractor. Thank you for your consideration!
My attempted to used collated promises seemed promising, but fell through on execution.
My Updated PageObject SpecMapper Class
import {browser, element, by, protractor} from 'protractor';
export class SpecMapperPage {
getImportDateSubmittedColumnValues() {
let promisesArray = [];
let stringDatesArray: Array<string> = [];
// This CSS selector grabs the import table and any cells with the label .created-date
element.all(by.css('.import-component .created-date')).each(function(cell, index) {
// cell.getText().then(function(text:string) {
// console.log(text);
// });
promisesArray.push(cell.getText());
});
return protractor.promise.all(promisesArray).then(function(results) {
for(let result of results) {
stringDatesArray.push(result);
}
return stringDatesArray;
});
}
}
My Updated Spec test Using The Updated SpecMapper PO Class
import { SpecMapperPage } from "./specMapper.po";
import {browser, ExpectedConditions} from "protractor";
describe('spec mapper app', () => {
let page: SpecMapperPage;
let PROJECT_ID: string = '57';
let PROJECT_NAME: string = 'DO NOT DELETE - AUTOMATED TESTING PROJECT';
beforeEach(() => {
page = new SpecMapperPage();
});
describe('import/export page', () => {
it('TC2963: ImportComponentGrid_ShouldDefaultSortBySubmittedDateInDescendingOrder_WhenPageIsLoaded', () => {
browser.waitForAngularEnabled(false);
// Step 1: Launch Map Data from Dashboard
page.navigateTo(PROJECT_ID);
browser.driver.sleep(5000).then(() => {
// Verify: Mapping Screen displays
// Verify on the specmapper page by checking the breadcrumbs
expect(page.getProjectNameBreadCrumbText()).toContain(PROJECT_NAME);
expect(page.getProjectMapperBreadCrumbText()).toEqual("MAPPER");
// Verify: Verify Latest Submitted Date is displayed at the top
// Verify: Verify the Submitted Date column is in descending order
page.getImportDateSubmittedColumnValues().then(function(results) {
for(let value of results) {
console.log("a value is: " + value);
}
});
});
});
});
});
When I breakpoint in the PO class at the return stringDatesArray; line, I have the following variables in my differing scopes. Note that the promisesArray has 3 objects, but the results array going into the protractor.promise.all( block has 0 objects. I'm not sure what my disconnect is. :/
I think I'm running into a scopes problem that I am having issues understanding. You'll note the commented out promise resolution on the getText(), and this was my POC proving that I am getting the string values I'm expecting, so I'm not sure why it's not working in the Promise Array structure presented as a solution below.
Only other related question that I could find has to do with grabbing a particular row of a table, not specifically aggregating the data to be returned for test verification in Protractor. You can find it here if you're interested.
As you've alluded to your issue is caused by the console.log returning the value of the variable before its actually been populated.
I've taken a snippet from this answer which should allow you to solve it: Is there a way to resolve multiple promises with Protractor?
var x = element(by.id('x')).sendKeys('xxx');
var y = element(by.id('y')).sendKeys('yyy');
var z = element(by.id('z')).sendKeys('zzz');
myFun(x,y,z);
//isEnabled() is contained in the expect() function, so it'll wait for
// myFun() promise to be fulfilled
expect(element(by.id('myButton')).isEnabled()).toBe(true);
// in a common function library
function myFun(Xel,Yel,Zel) {
return protractor.promise.all([Xel,Yel,Zel]).then(function(results){
var xText = results[0];
var yText = results[1];
var zText = results[2];
});
}
So in your code it would be something like
getImportDateSubmittedColumnValues() {
let promisesArray = [];
let stringDatesArray: Array<string> = [];
// currently this css selector gets rows in both import and export tables
// TODO: get better identifiers on the import and export tables and columns
element.all(by.css('md-card-content tbody tr.ng-tns-c3-0')).each(function(row, index){
// check outerHTML for presence of "unclickable", the rows in the export table
row.getAttribute('outerHTML').then(function(outerHTML:string) {
// specifically look for rows without unclickable
if(outerHTML.indexOf("unclickable") < 0){
// grab the columns and get the third column, where the date submitted field is
// TODO: get better identifiers on the import and export columns
promisesArray.push(row.all(by.css("td.ng-tns-c3-0")).get(2).getText());
}
});
});
return protractor.promise.all(promisesArray).then(function(results){
// In here you'll have access to the results
});
}
Theres quite a few different ways you could do it. You could process the data in that method at the end or I think you could return the array within that "then", and access it like so:
page.getImportDateSubmittedColumnValues().then((res) =>{
//And then here you will have access to the array
})
I don't do the Typescript but if you're just looking to get an array of locator texts back from your method, something resembling this should work...
getImportDateSubmittedColumnValues() {
let stringDatesArray: Array<string> = [];
$$('.import-component .created-date').each((cell, index) => {
cell.getText().then(text => {
stringDatesArray.push(text);
});
}).then(() => {
return stringDatesArray;
});
}
The answer ended up related to the answer posted on How do I return the response from an asynchronous call?
The final PageObject class function:
import {browser, element, by, protractor} from 'protractor';
export class SpecMapperPage {
getImportDateSubmittedColumnValues() {
let stringDatesArray: Array<string> = [];
let promisesArray = [];
// return a promise promising that stringDatesArray will have an array of dates
return new Promise((resolve, reject) => {
// This CSS selector grabs the import table and any cells with the label .created-date
element.all(by.css('.import-component .created-date')).map((cell) => {
// Gather all the getText's we want the text from
promisesArray.push(cell.getText());
}).then(() => {
protractor.promise.all(promisesArray).then((results) => {
// Resolve the getText's values and shove into array we want to return
for(let result of results) {
stringDatesArray.push(result);
}
}).then(() => {
// Set the filled array as the resolution to the returned promise
resolve(stringDatesArray);
});
});
});
}
}
The final test class:
import { SpecMapperPage } from "./specMapper.po";
import {browser, ExpectedConditions} from "protractor";
describe('spec mapper app', () => {
let page: SpecMapperPage;
let PROJECT_ID: string = '57';
let PROJECT_NAME: string = 'DO NOT DELETE - AUTOMATED TESTING PROJECT';
beforeEach(() => {
page = new SpecMapperPage();
});
describe('import/export page', () => {
it('TC2963: ImportComponentGrid_ShouldDefaultSortBySubmittedDateInDescendingOrder_WhenPageIsLoaded', () => {
browser.waitForAngularEnabled(false);
// Step 1: Launch Map Data from Dashboard
page.navigateTo(PROJECT_ID);
browser.driver.sleep(5000).then(() => {
// Verify: Mapping Screen displays
// Verify on the specmapper page by checking the breadcrumbs
expect(page.getProjectNameBreadCrumbText()).toContain(PROJECT_NAME);
expect(page.getProjectMapperBreadCrumbText()).toEqual("MAPPER");
// Verify: Verify Latest Submitted Date is displayed at the top
// Verify: Verify the Submitted Date column is in descending order
page.getImportDateSubmittedColumnValues().then((results) => {
console.log(results);
});
});
});
});
});
The biggest thing was waiting for the different calls to get done running and then waiting for the stringDataArray to be filled. That required the promise(resolve,reject) structure I found in the SO post noted above. I ended up using the lambda (()=>{}) function calls instead of declared (function(){}) for a cleaner look, the method works the same either way. None of the other proposed solutions successfully propagated the array of strings back to my test. I'm working in Typescript, with Protractor.

Categories

Resources