Querying collection using array meteor js - arrays

I have this weird scenario which I do not know what the problem is exactly. While troubleshooting I found out that the subscription is published and subscribed to because it's printed on the console. When I executed this on Firefox console it displayed this error SyntaxError: missing : after property id [Learn More]. I don't know what the syntax error is as the same code works on other files.
If I remove fetch() function from it it displayed 2 obects being published. This means the publish and sbscription is working. What am I to do right?
This is the event function
students(){
let myslug = trimInput(Session.get('ReceivedSlug'));
if (myslug) {
let mySchoolDoc = SchoolDb.findOne({slug: myslug});
if (mySchoolDoc) {
let arrayModuleSchool = StudentSchool.find({schoolId: mySchoolDoc._id});
if (arrayModuleSchool) {
var arrayStudentIds = [];
arrayModuleSchool.forEach(function(studentSchool){
arrayStudentIds.push(studentSchool.studentId);
});
let subReadiness = SchoolStudents.find({ _id: {$in: arrayStudentIds}}).fetch();
if (subReadiness) {
console.log('before readiness --- ' +arrayStudentIds);
console.log('after seting --- ' +subReadiness);
return subReadiness;
}
}
}
}
}
This is the publish function
Meteor.publish('PaginatedStudents', function (skipCount) {
check(skipCount, Number);
user = Meteor.users.findOne({_id:this.userId})
if(user) {
if(user.emails[0].verified) {
return SchoolStudents.find({userId: this.userId}, {limit: 2, skip: skipCount});
} else {
throw new Meteor.Error('Not authorized');
return false;
}
}
});
Tracker to rerun when things changes
Session.setDefault('skip', 0);
Tracker.autorun(function () {
Meteor.subscribe('PaginatedStudents', Session.get('skip'));
});

Related

getData() is not called when using authentication type of PATH_USER_PASS

I have encounter a problem when I am trying to build a google data studio community connector. Specifically, everything works and I can see the data rendered on the explorer screen if I user USER_PASS option of authentication, but if I use PATH_USER_PASS it doesn't render properly. When I look at the stack trace it doesn't even show that getData() function is executed. Can somebody help me?
publishing the code below from manifest file and hit CONNECT and EXPLORE will successfully give one row of data.
There will also be success when I change nothing but the AuthType to USER_PASS.
However, it will break when I change nothing but the AuthType to PATH_USER_PASS.
Note I hardcoded things into my getData and getSchema so running this code doesn't need any user input. The processing of getting data is not bind in any shape or form to the authentication process. This demonstrates this is possibly one of Google Data Studio's bugs.
As I said, getData() function is not even ran when I switch to PATH_USER_PATH authentication method.
Any help will be appreciated!!!!
main.js :
var cc = DataStudioApp.createCommunityConnector();
function getAuthType() {
return cc.newAuthTypeResponse()
.setAuthType(cc.AuthType.NONE)
.build();
}
function isAuthValid() {
return true;
}
function setCredentials(request) {}
function getConfig(request) {
var config = cc.getConfig();
return config.build();
}
function getSchema(request) {
var fields = getFields(request).build();
return { schema: fields };
}
function responseToRows(requestedFields, response) {
return response.map(function(submissions) {
var row = [];
requestedFields.asArray().forEach(function (field) {
switch (field.getId()) {
case 'student_name':
return row.push(submissions.student_name);
case 'student_age':
return row.push(submissions.student_age);
case 'student_school_year':
return row.push(submissions.student_school_year);
case 'submissionDate':
return row.push(submissions.__system.submissionDate)
default:
return row.push('');
}
});
return { values: row };
});
}
function getData(request) {
var requestedFieldIds = request.fields.map(function(field) {
return field.name;
});
var requestedFields = getFields().forIds(requestedFieldIds);
// fake response from hardCodedData.
var hardCodedData ='{"value":[{"__id":"uuid:3ab058df-5039-41cd-b16b-5c21f01bf60b","student_name":"Pieter Benjamin","student_age":21,"student_school_year":"Senior","select_student_school_year":"senior","__system":{"submissionDate":"2020-10-10T21:02:40.428Z","submitterId":"532","submitterName":"Pieter Benjamin","attachmentsPresent":0,"attachmentsExpected":0,"status":null},"meta":{"instanceID":"uuid:3ab058df-5039-41cd-b16b-5c21f01bf60b"}}],"#odata.context":"https://sandbox.central.getodk.org/v1/projects/124/forms/odata%20connector%20scheme.svc/$metadata#Submissions"}'
var parsedResponse = JSON.parse(hardCodedData).value;
var rows = responseToRows(requestedFields, parsedResponse);
return {
schema: requestedFields.build(),
rows: rows
};
}
// hard coded schema
function getFields(request) {
var cc = DataStudioApp.createCommunityConnector();
var fields = cc.getFields();
var types = cc.FieldType;
var aggregations = cc.AggregationType;
fields.newDimension()
.setId('student_name')
.setType(types.TEXT);
fields.newMetric()
.setId('student_age')
.setType(types.NUMBER);
fields.newMetric()
.setId('student_school_year')
.setType(types.TEXT);
fields.newDimension()
.setId('submissionDate')
.setType(types.YEAR_MONTH_DAY);
return fields;
}
function isAdminUser() {
return true;
}
appsscript.json:
{
"timeZone": "America/Los_Angeles",
"dependencies": {
},
"webapp": {
"access": "ANYONE",
"executeAs": "USER_ACCESSING"
},
"oauthScopes": ["https://www.googleapis.com/auth/script.external_request"],
"runtimeVersion": "V8",
"dataStudio": {
"name": "ODK central API connector",
"logoUrl": "https://getodk-a3b1.kxcdn.com/uploads/default/original/2X/3/381d364b5dd1069f6540bbd7a38ea48f11023ae9.jpg",
"company": "UW Impact++",
"companyUrl": "https://sites.google.com/view/udubimpact",
"addonUrl": "https://github.com/UDub-Impact/OData-Connector/blob/master/readme.md",
"supportUrl": "https://github.com/googledatastudio/community-connectors/issues",
"description": "Get your data from ODK central",
"sources": ["npm"],
"templates": {
"default": "1twu0sHjqR5dELAPyGJcw4GS3-D0_NTrQ"
}
}
}
As of 11/3/2020, this problem of not being able to use PATH_USER_PASS has been resolved. I didn't change any code but that option of authentication works now.

AngularJS: Passing Promise, yet Cannot read property 'finally' of undefined

In my angular app, I have 2 methods save() and saveTriggers(). saveTriggers() updates all records by calling a web service (C#). I want to make sure that a block of code is executed after all records are updated in saveTriggers() and control is returned to save(). I believe I need to pass something from the saveTriggers() to make finally block execute. I tried various things, nothing works. Using .then() also gives the same error. I am not that good at JS. Can you please guide me.
vm.updatedTriggers = []; // IDs are pushed in
vm.saveTriggers = function () {
if (vm.updatedTriggers.length === 0) {
vm.close();
} else {
vm.saving = true;
vm.save()
.finally(function () { // ERROR - Cannot read property 'finally' of undefined
console.log("Saved all. Closing..."); // Never REACHES here
vm.saving = false;
vm.updated = true;
$uibModalInstance.close(true);
});
}
};
vm.save = function () {
//vm.saving = true;
for (var i = 0; i < vm.updatedTriggers.length; i++) {
var trigger = vm.triggers.find(t => t.id === vm.updatedTriggers[i]);
var input = {
id: trigger.id,
target: trigger.target,
targetInfo: vm.targetData,
event: trigger.event,
eventQuantity: trigger.eventQuantity,
eventQuantityExtra: trigger.eventQuantityExtra
};
rpmService.editDeviceTrigger(input);
/*.finally(function () {
console.log("Updated event"); // Reaches here
vm.updated = true;
return Promise.resolve(2);
});*/ // Commenting this also doesn't help
}
return Promise.resolve(2);
};
rpmService.editDeviceTrigger(input)
public async Task EditDeviceTrigger(EditDeviceTriggerInput input) {
// calls other methods with await
// Doesn't return anything
}
EDIT: Updated Code: I got rid of the error, but the output is not is expected series.
vm.saveTriggers = function () {
vm.saving = true;
vm.save().then
(function success() {
console.log("Returned Result ");
console.log("Saved all. Closing..."); // These lines are executed before the event is upated
vm.saving = false;
$uibModalInstance.close(true);
});
};
vm.save = function () {
var deferred = $q.defer();
for (var i = 0; i < vm.updatedTriggers.length; i++) {
var trigger = vm.triggers.find(t => t.id === vm.updatedTriggers[i]);
var input = {
id: trigger.id,
....
};
rpmService.editDeviceTrigger(input)
.finally(function () {
console.log("Updated event"); // Successfully updates all events
vm.updated = true;
});
}
deferred.resolve();
return deferred.promise;
};
OUTPUT:
Returned Result
Saved all. Closing...
Updated event
EXPECTED OUTPUT:
Updated event
Returned Result
Saved all. Closing...
Thanks.
Usually you dont need $q.defer-related things, but u can do same using it if u want.
Here I guess you just need to collect all your save promises and return new resulting one using $q.all:
vm.save = function () {
const myAwesomePromises = []
for (var i = 0; i < vm.updatedTriggers.length; i++) {
...
const savePromise = rpmService.editDeviceTrigger(input);
savePromise.finally(() => console.log('edit device finally'));// <-- not sure u need this
myAwesomePromises.push(savePromise);
}
return $q.all(myAwesomePromises).finally(() => console.log('All edit device finally'));
};

Angular: What's the correct way to return Observable?

I have the following method which isn't working correct:
getProducts(): Observable<Product[]> {
let PRODUCTS: Product[];
this.http.get(this.base_url + "api/products")
.subscribe(
(data) => {
for(var i in data) {
PRODUCTS.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
},
(error) => {
console.log(error);
});
return of(PRODUCTS);
}
The error I'm getting is this:
TypeError: Cannot read property 'push' of undefined
Now, I know that the PRODUCT array is not accessable from within the subscribe function, but I cannot get the correct solution for it.
Can anyone help me with that. I want to return an Observable<Product[]>.
Thank you in advance!
Edit: Updated to account for the fact that the API seems to return an array-like object rather than a true array.
You want to use map:
getProducts(): Observable<Product[]> {
return this.http.get(this.base_url + "api/products")
.map(data => {
let products = [];
for (let i in data) {
products.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
return products;
})
.do(null, console.log);
}
Since #pixelbit's comment keeps getting upvotes despite being wrong, here's an example showing why it is wrong:
// Fakes a HTTP call which takes half a second to return
const api$ = Rx.Observable.of([1, 2, 3]).delay(500);
function getProducts() {
let products = [];
api$.subscribe(data => {
for (let i in data) {
products.push(data[i]);
}
});
return Rx.Observable.of(products);
}
// Logs '[]' instead of '[1, 2, 3]'
getProducts().subscribe(console.log);

Angular template won't load. Even with $loaded. Data resolves after Load

Using AngularFire, Angular, Firebase.
I load a list of users from a Firebase Database. I use $loaded to ensure it waits until data loads.
I take this list, compare it against another firebase database of groups and push the results into two arrays.
Based on the console.logs the data sorts correctly. However, inside my template I get a blank page (I think this is because the page loads before the data is sorted).
Thoughts?
let userLoggedIn = AuthFactory.getUser();
var allUsersArray = $firebaseArray(ConnectFactory.fbUserDb);
var x = firebase.database().ref('groups');
var friendArr = [];
var notFriendArr = [];
allUsersArray.$loaded().then(function(){
angular.forEach(allUsersArray, function(user, i) {
var haveIAdded = x.child(userLoggedIn).child(allUsersArray[i].uid).once('value').then(function (snap) {
if (snap.val() !== null) {
return true;
} else {
return false;
}
});
var haveTheyAdded = x.child(allUsersArray[i].uid).child(userLoggedIn).once('value').then(function (snap) {
if (snap.val() !== null) {
return true;
} else {
return false;
}
});
Promise.all([haveIAdded, haveTheyAdded]).then(function([you, they]) {
if (you && they) {
console.log('We Are Friends', allUsersArray[i]);
friendArr.push(allUsersArray[i]);
} else {
console.log('not a friend ', allUsersArray[i]);
notFriendArr.push(allUsersArray[i]);
}
});
});
$scope.friendList = friendArr;
$scope.notFriendList = notFriendArr;
});
Alright, this time I tried to actually read the question before attempting to answer. ;-)
When you set your $scope.friendList and $scope.notFriendList within the $loaded promise, your Promise.all may (and most likely) havn't resolved yet when those are called, since angular.forEach doesn't wait for the promises to finish before moving on to the next statement in the function. So you'll have to build an array of promises and wait for them all to resolve outside of the loop before attempting to set your $scope variables.
allUsersArray.$loaded().then(function(){
var promises = [];
var friendArr = [];
var notFriendArr = [];
angular.forEach(allUsersArray, function(user, i) {
... // Same as before
promises.push(
Promise.all([haveIAdded, haveTheyAdded]).then(function([you, they]) {
if (you && they) {
console.log('We Are Friends', allUsersArray[i]);
friendArr.push(allUsersArray[i]);
} else {
console.log('not a friend ', allUsersArray[i]);
notFriendArr.push(allUsersArray[i]);
}
})
);
});
Promise.all(promises).then(function(){
$scope.friendList = friendArr;
$scope.notFriendList = notFriendArr;
});
});

how to get excel cell data changed event using new api or Excel object in office.js

I am trying to find out how to get cell changed event using the Excel object
Excel.run(function (ctx) {
}
in office 2016.
is the context used by Office.context.document is same as context used in run function
found the answer for this.
Binding concept used earlier can be used now also as shown in the example https://github.com/OfficeDev/office-js-docs/blob/master/reference/excel/bindingcollection.md
(function () {
// Create myTable
Excel.run(function (ctx) {
var table = ctx.workbook.tables.add("Sheet1!A1:C4", true);
table.name = "myTable";
return ctx.sync().then(function () {
console.log("MyTable is Created!");
//Create a new table binding for myTable
Office.context.document.bindings.addFromNamedItemAsync("myTable", Office.CoercionType.Table, { id: "myBinding" }, function (asyncResult) {
if (asyncResult.status == "failed") {
console.log("Action failed with error: " + asyncResult.error.message);
}
else {
// If successful, add the event handler to the table binding.
Office.select("bindings#myBinding").addHandlerAsync(Office.EventType.BindingDataChanged, onBindingDataChanged);
}
});
})
.catch(function (error) {
console.log(JSON.stringify(error));
});
});
// When data in the table is changed, this event is triggered.
function onBindingDataChanged(eventArgs) {
Excel.run(function (ctx) {
// Highlight the table in orange to indicate data changed.
var fill = ctx.workbook.tables.getItem("myTable").getDataBodyRange().format.fill;
fill.load("color");
return ctx.sync().then(function () {
if (fill.color != "Orange") {
ctx.workbook.bindings.getItem(eventArgs.binding.id).getTable().getDataBodyRange().format.fill.color = "Orange";
console.log("The value in this table got changed!");
}
else
})
.then(ctx.sync)
.catch(function (error) {
console.log(JSON.stringify(error));
});
});
}
})();

Resources