Typescript and angular 2 - node.js

import { Injectable } from '#angular/core';
import { Grocery } from '../../auth/grocery.model';
export interface CartItem {
grocery: Grocery;
count: number;
amount: number;
}
export class Cart {
count: number = 0;
amount: number = 0;
items: CartItem[] = [];
}
#Injectable()
export class CartService {
cart: Cart = new Cart();
constructor(){}
/* constructor(private Cart: Cart) {
this.cart = Cart;
}*/
addGrocery(grocery: Grocery) {
console.log(this.cart);
console.log("gro" + grocery);
console.log(grocery.sno);
let item: CartItem = this.findItem(grocery.sno);
console.log("first" + item);
if (item) {
item.count++;
item.amount += grocery.cost;
console.log("item" + item.amount);
} else {
item = {
grocery: grocery,
count: 1,
amount: grocery.cost
};
console.log("else" + this.cart.items.push(item));
this.cart.items.push(item);
}
this.cart.count++;
this.cart.amount += grocery.cost;
console.log("cart" + this.cart.amount);
console.log(item);
console.log(this.cart);
return item;
}
removeProduct(grocery: Grocery) {
let item: CartItem = this.findItem(grocery.sno);
if (item) {
item.count--;
item.amount -= grocery.cost;
if (!item.count) {
this.remove(item);
}
this.cart.count--;
this.cart.amount -= grocery.cost;
}
return item;
}
removeItem(item: CartItem) {
this.remove(item);
this.cart.count -= item.count;
this.cart.amount -= item.amount;
}
findItem(id: string): CartItem {
for (let i = 0; i < this.cart.items.length; i++) {
if (this.cart.items[i].grocery.sno === id) {
return this.cart.items[i];
}
}
return null;
}
clearCart() {
this.cart.items = [];
this.cart.amount = 0;
this.cart.count = 0;
}
remove(item: CartItem) {
let indx: number = this.cart.items.indexOf(item);
if (indx !== -1) {
this.cart.items.splice(indx, 1);
}
}
}
when calling the cart variable from another component the cart is showing empty and the values are not incremented.
addGrocery(grocery: Grocery) {
console.log(this.cart);
console.log("gro" + grocery);
console.log(grocery.sno);
let item: CartItem = this.findItem(grocery.sno);
console.log("first" + item);
if (item) {
item.count++;
item.amount += grocery.cost;
console.log("item" + item.amount);
} else {
item = {
grocery: grocery,
count: 1,
amount: grocery.cost
};
console.log("else" + this.cart.items.push(item));
this.cart.items.push(item);
}
this.cart.count++;
this.cart.amount += grocery.cost;
console.log("cart" + this.cart.amount);
console.log(item);
console.log(this.cart);
return item;
}
In the above code the increment is being done
but in the below code it's showing initial values when calling cart from another component
#Injectable()
export class CartService {
cart: Cart = new Cart();
constructor(){}

Related

Loading jquery in chome extension service worker manifest v3

I am having a extension where it can notify about new items added to RSS feed reader
All works in v2, but v3 I am unable to load jquery into service worker, since chrome doesnt allow.
As a workaround I have added as module
"background": {
"service_worker": "js/background.js","type": "module"
},
But still its a issue and says ReferenceError: $ is not defined
at Object.parseFeed
Or is there a way I can tweak my code to read xml without jquery?
import $ as module from 'js/jquery-2.1.4.min.js';
var Storage = (function() {
return {
getFeeds: function(callback, returnArray, sortArray) {
returnArray = typeof returnArray !== 'undefined' ? returnArray : true;
sortArray = typeof sortArray !== 'undefined' ? sortArray : true;
chrome.storage.sync.get(function(dataObject) {
var result = dataObject;
if (returnArray) {
var feedArray = this.parseDataObjectIntoArray(dataObject);
result = sortArray ? this.sortArrayOfObjects(feedArray, 'position') : feedArray;
} else {
delete result['RssR:Settings'];
}
callback(result)
}.bind(this));
},
getFeedByUrl: function(feedUrl, callback) {
chrome.storage.sync.get(feedUrl, function(feedData) {
callback(feedData[feedUrl]);
});
},
removeFeedByUrl: function(feedUrl) {
chrome.storage.sync.remove(feedUrl);
},
saveFeedData: function(feedData) {
var saveFeed = {};
saveFeed[feedData.url] = feedData;
this.setDataObject(saveFeed);
},
parseDataObjectIntoArray: function(object) {
var array = [];
Object.keys(object).forEach(function(objectKey) {
if (objectKey.indexOf('RssR:Settings') !== 0) {
array.push(object[objectKey]);
}
});
return array;
},
sortArrayOfObjects: function(array, sortKey) {
array.sort(function(a, b) {
if (typeof a[sortKey] === 'undefined') {
return true;
} else if (typeof b[sortKey] === 'undefined') {
return false;
}
return a[sortKey] - b[sortKey];
});
return array;
},
clearAllData: function() {
chrome.storage.sync.clear();
},
setDataObject: function(dataObject) {
chrome.storage.sync.set(dataObject);
}
}
}());
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
function msToTime(ms) {
let seconds = (ms / 1000).toFixed(1);
let minutes = (ms / (1000 * 60)).toFixed(1);
let hours = (ms / (1000 * 60 * 60)).toFixed(1);
let days = (ms / (1000 * 60 * 60 * 24)).toFixed(1);
if (seconds < 60) return seconds + " Sec";
else if (minutes < 60) return minutes + " Min";
else if (hours < 24) return hours + " Hrs";
else return days + " Days"
}
var FeedService = (function() {
return {
downloadFeed: function(feed) {
if (!feed.url) {
return;
}
console.log(feed.url)
fetch(feed.url)
.then(response => response.text())
.then(xmlString => {
console.log(xmlString)
this.parseFeed(xmlString, feed);
}
)
.then(data => console.log(data))
},
parseFeed: function(rawData, existingFeedData) {
var newFeedData = {};
var $feedEntries = $(rawData).find("entry").length > 0 ? $(rawData).find("entry") : $(rawData).find('item');
var lastUpdate = Date.now()
console.log("Now = " + lastUpdate)
lastUpdate = (existingFeedData && existingFeedData.lastUpdate) || Date.now()
console.log("Last Update = " + lastUpdate)
console.log("existingFeedData = " + JSON.stringify(existingFeedData))
pubDates = [];
$feedEntries.each(function(index, elm) {
pubDates.push(new Date($(elm).find("pubDate").text()).getTime())
if (lastUpdate < new Date($(elm).find("pubDate").text()).getTime()) {
console.log($(elm).find("title").text().substring(0, 20));
chrome.notifications.create(
$(elm).find("link").text(), {
type: "basic",
iconUrl: "../icons/254.png",
title: $(elm).find("title").text(),
message: "(" + msToTime((Date.now() - new Date($(elm).find("pubDate").text()).getTime())) + ") ",
requireInteraction: true
},
function() {}
);
}
}.bind(this));
console.log("Max date = " + Math.max.apply(null, pubDates))
existingFeedData.lastUpdate = Math.max.apply(null, pubDates);
Storage.saveFeedData(existingFeedData);
},
getUrlForFeed: function($feed, feedSettings) {
if (feedSettings.linkType && $feed.find(feedSettings.linkType).length > 0) {
return $feed.find(feedSettings.linkType).text();
} else if ($feed.find('link').length == 1) {
return $feed.find('link').text();
} else {
if ($feed.find('link[rel="shorturl"]').length > 0) {
return $feed.find('link[rel="shorturl"]').attr('href');
} else if ($feed.find('link[rel="alternate"]').length > 0) {
return $feed.find('link[rel="alternate"]').attr('href');
} else if ($feed.find('link[rel="related"]').length > 0) {
return $feed.find('link[rel="related"]').attr('href');
} else {
return $feed.find('link').first();
}
}
},
saveFeed: function(existingFeedData, newFeedData) {
;
},
updateReadStatusOfNewItems: function(oldItems, newItems) {
if (typeof oldItems === 'undefined' || Object.keys(oldItems).length == 0 || Object.keys(newItems).length == 0) {
return newItems;
}
Object.keys(newItems).forEach(function(url) {
if (oldItems[url]) {
newItems[url].unread = oldItems[url].unread;
}
});
return newItems;
},
setNewBadge: function() {
chrome.browserAction.setBadgeText({
text: 'NEW'
});
}
};
}());
chrome.alarms.onAlarm.addListener(function(alarm) {
if (alarm.name == 'updateRssFeeds') {
console.log("Called!")
updateRssFeeds();
}
});
chrome.notifications.onClicked.addListener(function(notificationId) {
chrome.tabs.create({
url: notificationId
});
});
chrome.runtime.onInstalled.addListener(onInstall);
function onInstall() {
chrome.runtime.openOptionsPage();
chrome.alarms.create('updateRssFeeds', {
when: 0,
periodInMinutes: 1
});
}
function updateRssFeeds() {
Storage.getFeeds(function(feeds) {
feeds.forEach(function(feed) {
FeedService.downloadFeed(feed);
});
}, true, false)
}

Data changes only after closing the app in the background in SwiftUI

I´m using core data to safe date in my iOS app. On button click I safe data to core data. In a separate tab the data is used in computed properties to get averages out of the added values and display them to the view. This works but the data only updates after the app is closed in the background. I've tried to pass the data into a viewModel and pass the data with an Environment Object but that didn't work (Sorry if this isn't very precise, that's my first post).
import SwiftUI
struct HabitStatistics: View {
#Environment(\.managedObjectContext) private var viewContext
#FetchRequest(sortDescriptors: []) var habits: FetchedResults<Habit>
// MARK: Computing EarlyBird Property
var filteredEarlyBird: Int {
var earlyBird = 0
var counter = 0
for h in habits {
let component = Calendar.current.dateComponents([.hour, .minute], from: h.getUpTime ?? Date())
let hour = component.hour ?? 0
let minute = component.minute ?? 0
let difference = (hour * 60 + minute) - 270
earlyBird += difference
counter += 1
}
if counter != 0 {
earlyBird /= counter
return earlyBird
} else {
return 0
}
}
// MARK: Computing ateMeat Property
var filteredMeat: Int {
var total: Int {
if habits.count == 0 {
return 1
} else {
return habits.count
}
}
var count = 0
var perc = 0
for h in habits {
if h.ateMeat == 0 {
count += 1
}
}
perc = count * 100 / total
return perc
}
// MARK: Computing ateSuger Property
var filteredSugar: Int {
var total: Int {
if habits.count == 0 {
return 1
} else {
return habits.count
}
}
var count = 0
var perc = 0
for h in habits {
if h.ateSugar == 0 {
count += 1
}
}
perc = count * 100 / total
return perc
}
// MARK: Computing didSports Property
var filteredSport: Int {
var total: Int {
if habits.count == 0 {
return 1
} else {
return habits.count
}
}
var count = 0
var perc = 0
for h in habits {
if h.didSports == 1 {
count += 1
}
}
perc = count * 100 / total
return perc
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
// Headline
Text("This Week")
.bold()
VStack {
RectangleCard(textLeft: "Meatfree", textRight: "\(filteredMeat) %")
RectangleCard(textLeft: "Sugarfree", textRight: "\(filteredSugar) %")
RectangleCard(textLeft: "Sportsrate", textRight: "\(filteredSport)%")
RectangleCard(textLeft: "Average Time Loss", textRight: "\(filteredEarlyBird) Min lost")
}
}
}
}
import SwiftUI
struct DailyForm: View {
#Environment(\.managedObjectContext) private var viewContext
#EnvironmentObject var model: HabitModel
#State var getUpTime = Date()
#State var ateMeat = InputOptions.nein
#State var ateSugar = InputOptions.nein
#State var didSports = InputOptions.nein
var body: some View {
VStack {
HStack {
Button("Clear") {
clear()
}
Spacer()
Button("Add") {
addHabit()
clear()
}
}
.padding()
ScrollView (showsIndicators: false) {
VStack (alignment: .leading) {
AddPickerValues(getUpTime: $getUpTime,
ateMeat: $ateMeat,
ateSugar: $ateSugar,
didSports: $didSports)
}
.padding(.horizontal)
}
}
}
func clear() {
getUpTime = Date()
ateMeat = InputOptions.nein
ateSugar = InputOptions.nein
didSports = InputOptions.nein
}
func addHabit() {
let habit = Habit(context: viewContext)
habit.id = UUID()
habit.getUpTime = getUpTime
habit.ateMeat = convertValue(habit: ateMeat)
habit.ateSugar = convertValue(habit: ateSugar)
habit.didSports = convertValue(habit: didSports)
do {
try viewContext.save()
}
catch {
// Couldn't save the recipe
}
}
func convertValue (habit: InputOptions) -> Int {
if habit == InputOptions.nein {
return 0
} else {
return 1
}
}
}
This is working:
Main:
#main
struct coretatatestApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
TabView {
DailyForm()
.tabItem {
Label("Daily Form", systemImage: "calendar" )
}
HabitStatistics()
.tabItem {
Label("Statistics", systemImage: "chart.bar.fill" )
}
}
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
Statistics:
struct HabitStatistics: View {
#Environment(\.managedObjectContext) private var viewContext
#FetchRequest(sortDescriptors: []) var habits: FetchedResults<Habit>
// MARK: Computing EarlyBird Property
var filteredEarlyBird: Int {
var earlyBird = 0
var counter = 0
for h in habits {
let component = Calendar.current.dateComponents([.hour, .minute], from: h.getUpTime ?? Date())
let hour = component.hour ?? 0
let minute = component.minute ?? 0
let difference = (hour * 60 + minute) - 270
earlyBird += difference
counter += 1
}
if counter != 0 {
earlyBird /= counter
return earlyBird
} else {
return 0
}
}
// MARK: Computing ateMeat Property
var filteredMeat: Int {
var total: Int {
if habits.count == 0 {
return 1
} else {
return habits.count
}
}
var count = 0
var perc = 0
for h in habits {
if h.ateMeat == false {
count += 1
}
}
perc = count * 100 / total
return perc
}
// MARK: Computing ateSuger Property
var filteredSugar: Int {
var total: Int {
if habits.count == 0 {
return 1
} else {
return habits.count
}
}
var count = 0
var perc = 0
for h in habits {
if h.ateSugar == false {
count += 1
}
}
perc = count * 100 / total
return perc
}
// MARK: Computing didSports Property
var filteredSport: Int {
var total: Int {
if habits.count == 0 {
return 1
} else {
return habits.count
}
}
var count = 0
var perc = 0
for h in habits {
if h.didSports == true {
count += 1
}
}
perc = count * 100 / total
return perc
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
// Headline
Text("This Week")
.bold()
VStack {
Text("Meatfree \(filteredMeat) %")
Text("Sugarfree \(filteredSugar) %")
Text("Sportsrate \(filteredSport)%")
Text("Average Time Loss \(filteredEarlyBird) Min lost")
}
}
}
}
Daily Form:
struct DailyForm: View {
#Environment(\.managedObjectContext) private var viewContext
// #EnvironmentObject var model: HabitModel
#FetchRequest(sortDescriptors: []) var habits: FetchedResults<Habit>
#State var getUpTime = Date()
#State var ateMeat = false
#State var ateSugar = false
#State var didSports = false
var body: some View {
VStack {
HStack {
Button("Clear") {
clear()
}
Spacer()
Button("Add") {
addHabit()
clear()
}
}
.padding()
ScrollView (showsIndicators: false) {
VStack (alignment: .leading) {
DatePicker("Get up Time", selection: $getUpTime, displayedComponents: .hourAndMinute)
Toggle("Ate Meat?", isOn: $ateMeat)
Toggle("Ate Sugar?", isOn: $ateSugar)
Toggle("Did Sports?", isOn: $didSports)
}
.padding(.horizontal)
}
}
}
func clear() {
getUpTime = Date()
ateMeat = false
ateSugar = false
didSports = false
}
func addHabit() {
let habit = Habit(context: viewContext)
habit.id = UUID()
habit.getUpTime = getUpTime
habit.ateMeat = ateMeat
habit.ateSugar = ateSugar
habit.didSports = didSports
do {
try viewContext.save()
}
catch {
// Couldn't save the recipe
}
}
}

Ag-grid infinite model pagination server-side

I'm attempting to use ag-grid with server side pagination. I updated the code sample from the ag-grid website ( below ). I retrieve the columnDefs in the ngOnInit method but alas neither the columnHeaders appear nor the rowdata. I can debug into the GetRows function and see that the rows are coming back. The total number of records gets set correctly.
If anyone can see why the grid's not showing the columns/rows I'd really appreciate it.
This is the output in the console.
ag-Grid.RowNodeBlockLoader: printCacheStatus: activePageLoadsCount = 0, blocks = {"0":{"blockNumber":0,"startRow":0,"endRow":10,"pageStatus":"loaded"}}
ag-Grid.RowNodeBlockLoader: checkBlockToLoad: no pages to load
ag-Grid.InfiniteCache: onPageLoaded: page = 0, lastRow = 5
but while the total number of records is returned from the call and sets
import { Component, OnInit, Input } from '#angular/core';
import {TableMetadata} from "../model/table-metadata";
import { HttpClient } from "#angular/common/http";
import { GridOptions } from "ag-grid";
import { BrxTableService } from '../service/brx-table.service';
#Component({
selector: 'app-brx-delta-agrid',
// templateUrl: './brx-delta-agrid.component.html',
template: `<ag-grid-angular
#agGrid
style="width: 100%; height: 100%;"
id="myGrid"
class="ag-theme-balham"
[columnDefs]="columnDefs"
[components]="components"
[floatingFilter]="true"
[debug]="true"
[enableServerSideSorting]="true"
[enableServerSideFilter]="true"
[enableColResize]="true"
[rowSelection]="rowSelection"
[rowDeselection]="true"
[rowModelType]="rowModelType"
[paginationPageSize]="paginationPageSize"
[cacheOverflowSize]="cacheOverflowSize"
[maxConcurrentDatasourceRequests]="maxConcurrentDatasourceRequests"
[infiniteInitialRowCount]="infiniteInitialRowCount"
[maxBlocksInCache]="maxBlocksInCache"
[pagination]="true"
[cacheBlockSize]="cacheBlockSize"
[getRowNodeId]="getRowNodeId"
(gridReady)="onGridReady($event)"
></ag-grid-angular>
`,
styleUrls: ['./brx-delta-agrid.component.css'],
providers: [BrxTableService]
})
export class BrxDeltaAgridComponent implements OnInit{
public state = {
skip: 0,
take: 5
};
private columnDefs = [];
private gridApi;
private gridColumnApi;
private components;
private rowSelection;
private rowModelType;
private paginationPageSize;
private cacheBlockSize;
private cacheOverflowSize;
private maxConcurrentDatasourceRequests;
private infiniteInitialRowCount;
private maxBlocksInCache;
private getRowNodeId;
#Input('tableMetadata') tableMetadata:TableMetadata;
constructor(private http: HttpClient, private brxTableService:BrxTableService) {
this.components = {
loadingRenderer: function(params) {
if (params.value !== undefined) {
return params.value;
} else {
return '<img src="../assets/loading.gif">';
}
}
};
this.rowSelection = "multiple";
this.rowModelType = "infinite";
this.paginationPageSize = 10;
this.cacheBlockSize = 10;
this.cacheOverflowSize = 2;
this.maxConcurrentDatasourceRequests = 2;
this.infiniteInitialRowCount = 1;
this.maxBlocksInCache = 2;
this.getRowNodeId = function(item) {
return item.R_ID;
};
}
ngOnInit() {
this.columnDefs = this.getColumnDefs();
}
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.http
.get("http://localhost:8080/api/"+ this.tableMetadata.tableName)
.subscribe(data => {
data._embedded[this.tableMetadata.tableName +"s"].forEach(function(data, index) {
data.R_ID = "R" + (index + 1);
});
var dataSource = {
rowCount: null,
getRows: function(params) {
console.log("asking ford " + params.startRow + " to " + params.endRow);
setTimeout(function() {
let collectionName ='';
for (var property in data._embedded) {
if (property.startsWith("BRX")) {
collectionName = property;
}
}
var dataAfterSortingAndFiltering = sortAndFilter(data._embedded[collectionName], params.sortModel, params.filterModel);
var rowsThisPage = dataAfterSortingAndFiltering.slice(params.startRow, params.endRow);
var lastRow = 5; // data.page.totalElements;
// if (dataAfterSortingAndFiltering.length <= params.endRow) {
// lastRow = dataAfterSortingAndFiltering.length;
// }
params.successCallback(rowsThisPage, lastRow);
}, 500 );
}
};
params.api.setDatasource(dataSource);
});
}
public getColumnDefs() {
let columnDefs = [];
for (let i=0; i<this.tableMetadata.columnNames.length; i++) {
let columnName = this.tableMetadata.columnNames[i];
let columnDef = {
headerName: columnName,
field: columnName,
width:100
};
columnDefs.push(columnDef);
}
return columnDefs;
}
}
function sortAndFilter(allOfTheData, sortModel, filterModel) {
return sortData(sortModel, filterData(filterModel, allOfTheData));
}
function sortData(sortModel, data) {
var sortPresent = sortModel && sortModel.length > 0;
if (!sortPresent) {
return data;
}
var resultOfSort = data.slice();
resultOfSort.sort(function(a, b) {
for (var k = 0; k < sortModel.length; k++) {
var sortColModel = sortModel[k];
var valueA = a[sortColModel.colId];
var valueB = b[sortColModel.colId];
if (valueA == valueB) {
continue;
}
var sortDirection = sortColModel.sort === "asc" ? 1 : -1;
if (valueA > valueB) {
return sortDirection;
} else {
return sortDirection * -1;
}
}
return 0;
});
return resultOfSort;
}
function filterData(filterModel, data) {
var filterPresent = filterModel && Object.keys(filterModel).length > 0;
if (!filterPresent) {
return data;
}
var resultOfFilter = [];
for (var i = 0; i < data.length; i++) {
var item = data[i];
if (filterModel.age) {
var age = item.age;
var allowedAge = parseInt(filterModel.age.filter);
if (filterModel.age.type == "equals") {
if (age !== allowedAge) {
continue;
}
} else if (filterModel.age.type == "lessThan") {
if (age >= allowedAge) {
continue;
}
} else {
if (age <= allowedAge) {
continue;
}
}
}
if (filterModel.year) {
if (filterModel.year.values.indexOf(item.year.toString()) < 0) {
continue;
}
}
if (filterModel.country) {
if (filterModel.country.values.indexOf(item.country) < 0) {
continue;
}
}
resultOfFilter.push(item);
}
return resultOfFilter;
}
style="width: 100%; height: 100%;"
Hi folks, facepalm time... The height here was set to 100%. The table was located in an overlay that had a width of zero at the time of rendering so the rows and column headers never rendered.
I still can't get continuous server requests happening with the pagination but at least i can see the data :)
Hope this example helps someone because I couldn't find many examples online.
Thanks,
Mark.

How to optimize query for super user?

I am doing the following query in pseudo code:
Give me all users in age range (provided by user input)
User's who have been seen the least recent first (10 at a time)
User's interest must include one of my interests
User's who have not been swiped left or right by me
If I swiped through 1,000 users and then someone swiped all the same 1,000 then a new user is added making it 1,001. Since all the other 1,000 have been least recent since each new user gets the most recent being the date they create their account, then it has to go through the 1,000 before getting to 1,001 leading to a 3-4 minute query call which is not ok.
My current stack includes Javascript for my web, Backend uses NodeJs with Mongodb.
The three queries look like this:
var minAge = (req.body.min);
var maxAge = (req.body.max);
var swipersCount = 0;
verifyLoginFilter(req, function(loggedIn, userObj, uid) {
if (loggedIn && !userObj.accountFrozen) {
//doing -1 on min and +1 on max for inclusive
var minAgeMinusOne = minAge - 1;
if (minAge === 0) {
minAgeMinusOne = 0;
}
var maxAgePlusOne = maxAge + 1;
var theSwipers, swipersInterests;
var x = 0;
var y = 0;
var skipCount = 0;
grabSwiperLastSwiped();
function grabSwiperLastSwiped() {
User.find({
"$and": [
{ accountFrozen: false },
{ creditsAvailable: { $gt: minAgeMinusOne } },
{ userId: { $ne: uid } }, {
"$or": [
{ "minAge": { "$lt": maxAgePlusOne, "$gt": minAgeMinusOne } },
{ "maxAge": { "$lt": maxAgePlusOne, "$gt": minAgeMinusOne } }
]
}
]
})
.limit(10).sort({ dateLastSwiped: 1 }).skip(skipCount).select({ userId: 1, activeInterests: 1, creditsAvailable: 1, dateLastSwiped: 1 })
.exec(function(err, swipers) {
if (err) {
return res.json({ statusCode: alertErrors.mongodb });
} else {
if (swipers.length > 0) {
theSwipers = swipers;
grabSwiperInterests();
} else {
return res.json({ statusCode: alertErrors.noSwipers });
}
}
});
}
function grabSwiperInterests() {
var today = new Date();
var finalMax;
if (theSwipers[x].creditsAvailable > maxAgePlusOne) {
finalMax = maxAgePlusOne;
} else {
finalMax = theSwipers[x].creditsAvailable;
}
Interests.
find({
"$and": [
{ userId: theSwipers[x].userId },
{ paused: false },
{ _id: { $nin: userObj.personSwiped } }
]
}).limit(10)
.sort({ dailyCredits: 1 })
.exec(function(err, interests) {
if (err) {
return res.json({ statusCode: alertErrors.mongodb });
} else {
if (interests.length > 0) {
swipersInterests = interests;
checkInterst();
} else {
nextSwiper();
}
}
});
}
function nextSwiper() {
swiperCount++;
console.log("nextSwiper " + theSwipers[x].userId + " number " + swiperCount);
if (x === theSwipers.length - 1) {
x = 0;
skipCount = skipCount + theSwipers.length;
grabSwiperLastSwiped();
} else {
console.log("nextSwiper " + theSwipers.length + " x " + x);
x++;
grabSwiperInterests();
}
}
function nextInterest() {
console.log("nextInterest");
if (y === swipersInterests.length - 1) {
nextSwiper();
} else {
y++;
checkInterst();
}
}

I am trying to export rallygrid data in excel file, but getting only headers not values

I am trying to export rallygrid data in excel file, but getting only headers not values.
Below is my code which I wrote to generate grid and export button
From here [https://github.com/andreano/TaskDelta/blob/master/App.js], I stole the export code
prepareChart: function(iteration_data) {
this.converted_values = [];
this.accept_values = [];
this.commit_values = [];
parents = [];
rootParent = this.getContext().getProject().Name;
sortedArray = [];
var project_hash = {}; // project_by_name, with children
Ext.Array.each(iteration_data, function(iteration){
if ((iteration.ProjectName != rootParent && iteration.ChildCount > 0) || iteration.ParentName == rootParent) {
parents.push(iteration.ProjectName);
}
// make a place for me
if ( ! project_hash[iteration.ProjectName] ) { project_hash[iteration.ProjectName] = []; }
// make a place for my parent so it can know children
if ( iteration.ParentName ) {
if ( ! project_hash[iteration.ParentName]) { project_hash[iteration.ParentName] = []; }
project_hash[iteration.ParentName] = Ext.Array.merge( project_hash[iteration.ParentName], iteration.ProjectName);
}
}, this);
// build order this way:
//console.log("Current: ", this.getContext().getProject().Name );
// order the array by parents to children to grandchildren
sortedArray = this._getTreeArray( this.getContext().getProject().Name , project_hash);
parents = Ext.Array.unique(parents);
sortedData = [];
Ext.Array.each(sortedArray, function(name){
Ext.Array.each(iteration_data, function(ite){
if(ite.ProjectName == name) {
sortedData.push(ite);
};
});
});
Ext.Array.each(iteration_data, function(iteration){
if (iteration.ProjectName == rootParent) {
sortedData.push(iteration);
}
}, this);
iteration_data = sortedData;
sprints = [];
teams = [];
this.ratio = {};
for ( var i=0; i<iteration_data.length; i++ ) {
commit_accept_ratio = 0;
var data_point = iteration_data[i];
this.commit_values.push( data_point.Commit );
this.accept_values.push( data_point.Accept );
if ( data_point.Commit > data_point.Accept ) {
this.converted_values.push( data_point.Commit - data_point.Accept );
} else {
this.converted_values.push( 0 );
}
if (data_point.Commit != 0) {
commit_accept_ratio = (data_point.Accept / data_point.Commit ) * 100;
} else {
commit_accept_ratio = 0;
};
sprints.push(iteration_data[i].Name);
teams.push(iteration_data[i].ProjectName);
teams.push(rootParent);
this.ratio[data_point.ObjectID] = commit_accept_ratio;
}
this.sprints = Ext.Array.unique(sprints).sort();
this.teams = Ext.Array.unique(teams);
removable_teams = [];
for ( var i=0; i<this.teams.length; i++ ) {
team_name = null;
var count = 0;
Ext.Array.each(iteration_data, function(data) {
if (this.teams[i] == data.ProjectName && data.Commit == 0 || null || undefined && data.Accept == 0 || null || undefined) {
count += 1;
team_name = data.ProjectName;
}
}, this);
if (count == this.sprints.length) {
removable_teams.push(team_name);
}
}
removable_teams = Ext.Array.unique(removable_teams);
records = [];
recordHash = {};
summaryHash = {};
Ext.Array.each(iteration_data, function(iter) {
if (!recordHash[iter.ProjectName]) {
recordHash[iter.ProjectName] = {
Team: iter.ProjectName,
Name: '4 Sprint Summary',
Commit: [],
Accept: [],
Perc: [],
Summary: 0
};
}
if (!Ext.Array.contains(removable_teams, iter.ProjectName)) {
recordHash[iter.ProjectName]["Commit-" + iter.Name] = iter.Commit;
recordHash[iter.ProjectName]["Accept-" + iter.Name] = iter.Accept;
recordHash[iter.ProjectName]["Perc-" + iter.Name] = this.ratio[iter.ObjectID];
}
}, this);
var summaryArray = Ext.Array.slice( this.sprints, (this.sprints.length - 4))
var iterated_data = [];
Ext.Array.each(summaryArray, function(summ){
Ext.Array.each(iteration_data, function(team) {
if( summ == team.Name){
iterated_data.push(team);
}
});
});
Ext.Array.each(iteration_data, function(summ){
Ext.Array.each(iterated_data, function(team) {
if (!summaryHash[team.ProjectName]) {
summaryHash[team.ProjectName] = {
Commit: 0,
Accept: 0,
Total: 0
};
};
if (!Ext.Array.contains(removable_teams, team.ProjectName)) {
if( summ.ProjectName == team.ProjectName && summ.Name == team.Name) {
summaryHash[team.ProjectName]["Commit"] += summ.Commit;
summaryHash[team.ProjectName]["Accept"] += summ.Accept;
if (summaryHash[team.ProjectName]["Commit"] != 0) {
summaryHash[team.ProjectName]["Total"] = (summaryHash[team.ProjectName]["Accept"] / summaryHash[team.ProjectName]["Commit"] ) * 100;
} else {
summaryHash[team.ProjectName]["Total"] = 0;
};
};
}
});
}, this);
Ext.Object.each(recordHash, function(key, value) {
if (summaryHash[key]) {
value["Summary"] = summaryHash[key].Total;
records.push(value);
}
});
var cfgsValues = [];
cfgsValues.push({text: 'Team', style:"background-color: #D2EBC8", dataIndex: 'Team', width: 170, renderer: function(value, meta_data, record, row, col) {
if (Ext.Array.contains(parents, value)) {
meta_data.style = "background-color: #FFF09E";
return Ext.String.format("<div style='font-weight:bold;text-align:center'>{0}</div>", value);
} else if (rootParent == value){
meta_data.style = "background-color: #CC6699";
return Ext.String.format("<div style='font-weight:bold;text-align:center'>{0}</div>", value);
} else {
return value;
};
}});
cfgsValues.push({text: '4 Sprint Summary', style:"background-color: #D2EBC8", width: 70, dataIndex: 'Summary', renderer: function(value, meta_data, record) {
var color = null;
if (value >= 80 && value <= 120) {
color = "#00AF4F";
}
else if (value >= 60 && value <= 80) {
color = "#FBFE08";
}
else if (value <= 60) {
color = "#FC0002";
}
else if (value >= 120) {
color = "#98CCFB";
};
meta_data.style = "background-color: "+color+"";
return Ext.Number.toFixed(value, 0)+"%";
}});
Ext.Array.each(this.sprints, function(sprint) {
cfgsValues.push(
{text: sprint, style:'background-color:#D2EBC8;text-align:center;font-weight:bold', defaults: {enableColumnHide:false}, columns:[
{text: "Commit", dataIndex: 'Commit-' + sprint, width: 50, renderer: function(value, meta_data, record) {
if( value ) {
return value;
} else {
return "NA";
}
}},
{text: "Accept", dataIndex: 'Accept-' + sprint, width: 60, renderer: function(value, meta_data, record) {
if( value) {
return value;
} else {
return "NA";
}
}},
{text: "%", dataIndex: 'Perc-'+ sprint, width: 50, renderer: function(value, meta_data, record) {
var color = null;
if (value >= 80 && value <= 120) {
color = "#00AF4F";
}
else if (value >= 60 && value <= 80) {
color = "#FBFE08";
}
else if (value <= 60) {
color = "#FC0002";
}
else if (value >= 120) {
color = "#98CCFB";
}
meta_data.style = "background-color: "+color+"";
if (value) {
return Ext.Number.toFixed(value, 0)+"%";
} else {
return "NA";
};
}}
]}
);
});
var chart = Ext.getCmp('mychart');
if (chart) {
chart.destroy();
};
Ext.Array.each(this.sprints, function(sprint) {
Ext.Array.each(records, function(record) {
if (record["Accept-" + sprint] == undefined) {
record["Accept-" + sprint] = undefined;
}
if (record["Commit-" + sprint] == undefined) {
record["Commit-" + sprint] = undefined;
}
if (record["Perc-" + sprint] == undefined) {
record["Perc-" + sprint] = undefined;
}
});
});
this.add({
xtype: 'rallygrid',
id: 'mychart',
store: Ext.create('Rally.data.custom.Store', {
data: records,
pageSize: 100
}),
//viewConfig: {
//stripeRows: false
//},
columnCfgs: cfgsValues,
//columnLines: true
});
this.globalStore = Ext.getCmp('mychart');
console.log("this.globalStore", this.globalStore);
this.down('#grid_box').add(this.globalStore);
//this.setLoading(false);
},
_addPrintButton: function() {
var me = this;
this.down('#print_button_box').add( {
xtype: 'rallybutton',
itemId: 'print_button',
text: 'Export to Excel',
disabled: false,
margin: '20 10 10 0',
region: "right",
handler: function() {
me._onClickExport();
}
});
},
_onClickExport: function () { //using this function to export to csv
var that = this;
if (this.down('#grid_box')){
//Ext.getBody().mask('Exporting Tasks...');
//console.log('inside export');
setTimeout(function () {
var template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-' +
'microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head>' +
'<!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>' +
'{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>' +
'</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}' +
'</table></body></html>';
var base64 = function (s) {
return window.btoa(unescape(encodeURIComponent(s)));
};
var format = function (s, c) {
return s.replace(/{(\w+)}/g, function (m, p) {
return c[p];
});
};
var table = that.getComponent('grid_box');
//console.log("Exporting table ",table);
var excel_data = '<tr>';
Ext.Array.each(table.getEl().dom.outerHTML.match(/<span .*?x-column-header-text.*?>.*?<\/span>/gm), function (column_header_span) {
excel_data += (column_header_span.replace(/span/g, 'td'));
});
excel_data += '</tr>';
Ext.Array.each(table.getEl().dom.outerHTML.match(/<tr class="x-grid-row.*?<\/tr>/gm), function (line) {
excel_data += line.replace(/[^\011\012\015\040-\177]/g, '>>');
});
//console.log("Excel data ",excel_data);
var ctx = {worksheet: name || 'Worksheet', table: excel_data};
window.location.href = 'data:application/vnd.ms-excel;base64,' + base64(format(template, ctx));
Ext.getBody().unmask();
}, 500);
}else{
console.log("grid_box does not exist");
}
}
There is an example in new AppSDK2 documentation of exporting to CSV.
I also have an example of exporting to CSV in this github repo.

Resources