Datastudio Community Connector - Add filter - google-data-studio

I have a site with hundreds of members who would like to see activity relating to their products. We use datastudio at the moment, creating a report manually for a few who have asked.
We would like to be able to send out a single report that grabs the member details from the url and sets the report to that member. We followed the datastudio docs https://developers.google.com/datastudio/solution/viewers-cred-with-3p-credentials but it's not very clear
function getAuthType() {
var response = { type: 'NONE' };
return response;
}
function getConfig(request) {
var cc = DataStudioApp.createCommunityConnector();
var config = cc.getConfig();
config
.newTextInput()
.setId('token')
.setName('Enter user token')
.setAllowOverride(true);
config.setDateRangeRequired(false);
config.setIsSteppedConfig(false);
return config.build();
}
function getFields(request) {
var cc = DataStudioApp.createCommunityConnector();
var fields = cc.getFields();
var types = cc.FieldType;
fields.newDimension()
.setId('tokenValue')
.setType(types.TEXT);
return fields;
}
function getSchema(request) {
var fields = getFields(request).build();
return { schema: fields };
}
function getData(request) {
var token = request.configParams.token;
}
Has anyone set up a community connector that would allow multiple users to see a single report but only see what's specific to them?
I'm not sure if the token is being set property. It displays as the placeholder only. Is there a way to be sure what value my parameter is assigned?
We haven't got the the point of passing a url parameter. What we would like to do is pass the token value (Member details) to an existing filter. Is this possible in a community connector?

You can use the Filter by email address feature to filter your data based on the viewer's email address. This works out of the box and won't require you to build a custom connector.
Alternatively, if you do want to build a custom connector, follow this guide that seems more suitable for your use case.

Related

Google.Cloud.AppEngine.V1 client libraries and traffic splitting in .NET

I am trying to use the Client Libraries provided by Google to move traffic from one version of an app in AppEngine to another. However, the documentation for doing this just talks about using the rest API and not the client libraries.
Here is some example code:
var servicesClient = Google.Cloud.AppEngine.V1.ServicesClient.Create();
var updateServiceRequest = new UpdateServiceRequest();
updateServiceRequest.Name = "apps/myProject/services/myService";
var updateMask = new Google.Protobuf.WellKnownTypes.FieldMask();
updateServiceRequest.UpdateMask = updateMask;
// See below for what should go here...
var updateResponse = servicesClient.UpdateService(updateServiceRequest);
My question is what format do I use for the update mask?
According to the documentation I should put in:
split {"split": { "allocations": { "newVersion": 1 } } }
But when I try: updateMask.Paths.Add(#"split { ""split"": { ""allocations"": { ""myNewVersion"": 1 } } }");
... I get the exception:
"This operation is only supported on the following field(s): [labels, migration_config, network_settings, split, tag_to_target_map], but got field(s): [split { "split": { "allocations": { "myNewVersion": 1 } } }] from the update request.
Any ideas where I should put the details of the split in the field mask object? The property Paths just seems to be a collection of strings.
The examples for these libraries in Google's doco is pretty poor :-(
I raised a support ticket with Google and despite them suggesting a solution which didn't work exactly (due to trying to assign a string to the UpdateMask which needs a FieldMask object), I managed to use it to find the correct solution.
The code should be:
// appService is a previously retrieved Service object from the ListServices method
var updateServiceRequest = new UpdateServiceRequest();
updateServiceRequest.Name = appService.Name;
updateServiceRequest.UpdateMask = new Google.Protobuf.WellKnownTypes.FieldMask();
updateServiceRequest.UpdateMask.Paths.Add("split");
appService.Split.Allocations.Clear();
appService.Split.Allocations["newServiceVerison"] = 1;
updateServiceRequest.Service = appService;

how to query sails-disk in sailsjs

I have generated the api in sailsjs using
sails generate api testAPI
and I have been able to create data using the command
http://localhost:1337/testAPI/create?username=f1&password=123
and i can get the result
but when I want to customize the route
for get - http://localhost:1337/testAPI/1
i am using the code
module.exports = {
findOne:function(req,res){
res.ok('overridden');
}
};
in testAPIController.js for the overriding
and when I go the route http://localhost:1337/testAPI/1 I am able to see overriden displayed there.
but how do I query the data and show a customized view there?
to customize and query the data I am using this code and it doesnt work
says that testAPI not defined
module.exports = {
findOne:function(req,res){
var results = testAPI.find()
res.ok(results);
}
};
so, what am I doing wrong here?
The model you created should be used with the first capital letter (TestAPI.find());
Also, you should consider the assync factor when fetching data. See code bellow
module.exports = {
findOne:function(req,res){
TestAPI.find().then(function(results) {
return res.ok(results);
});
}
};

im trying to update database record with function return Ionic, Back&

Hi I'm trying to update my database with function that returns a number
$scope.sum = function()
{
return $scope.inp + $scope.points;
};
this function will update the record in object points, column name and id 1:
$scope.addPoint = function() {
PointService.addPoint($scope.sum, 1)
.then(function(result) {
$scope.inp = 0;
getMyPoints();
});
}
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),points,name);
}
the error is: Error details: Cannot convert type 'int' to 'System.Collections.Generic.Dictionary'
the data type of the field is Float.
Any idea what is wrong with the code?
you are passing function reference to PointService.addPointer(),
use this:
$scope.addPoint = function() {
PointService.addPoint($scope.sum(), 1) // NOT PointService.addPoint($scope.sum, 1)
.then(function(result) {
$scope.inp = 0;
getMyPoints();
});
}
this will execute your function and pass the output (id parameter) to addPoint function, further, for more safe side, you can return Number from $scope.sum() i.e.
$scope.sum = function()
{
return Number($scope.inp + $scope.points);
};
This looks like an issue with how you're contacting Backand. You use the following code to send your points over:
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),points,name);
}
This is an older version of calling the Backand API that is manually constructing a PUT request, and putting "points" and "name" as the "Data" and "config" parameters to $http. With an object update via PUT, you'll need to provide the updates as an object. So if you wanted to update the points and the name of the object (and I'm doing some assuming based upon what I can tell from the code snippet above), you'd need to encapsulate these properties in an object that has the following general format:
{
"field_name_1":"new value_1",
"field_name_2":"new value_2",
etc ...
}
This should then be sent as the body of the request. So, for your code, change it to the following and see if this helps:
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),{points: points, name: name});
}
To give more info on why you're seeing this particular error, Backand is depending on this JSON format in the body. Our platform should definitely do more validation (and I'll create a ticket for the devs to handle non-conforming input more gracefully), but at the moment we simply take the body of the request, convert it to a dictionary object, then begin the requested operation. As your code above sends only "1.0" as the body, this fails the conversion into a dictionary, causing the stack exception and the issue you are seeing.
As a note, we offer a new SDK that encapsulates these HTTP methods, performing the authentication header generation and HTTP messaging for you, providing promises to handle responses. You can find it on our Github page at https://github.com/backand/vanilla-sdk. To make the same call using the new SDK, the code would resemble the following:
backand.object.update("your object name", 1, {name: name, points: points})
.then(function(response){
console.log(response.data);
});

How to add to a list in Firebase without overwriting

I am trying to create a 'Favorites' section in my app where you hit a button and it is added to a user favorites list in firebase. I am using the ionic platform.
I created a factory to handle the favourites as they come in. and i use the getAuth() function to get the unique userID so i can just pull it when the user logs on. This is my attempt but i am not getting the result i wanted which is simply something like :
< userid >:
{
0: "fav1"
1: "fav2"
}
.factory('Favourites',function($firebaseArray){
var ref = new Firebase("https://experiencett.firebaseio.com/");
var authData = ref.getAuth();
var favs = $firebaseArray(new Firebase('https://experiencett.firebaseio.com/favourites/'+authData.uid+''));
return {
all: function() {
return favs;
},
add: function(){
var up=new Firebase('https://experiencett.firebaseio.com/favourites/');
var usersref=up.child(authData.uid);
usersref.push({3:"paria"});
},
When you call push() you are generating a unique id. While that is great for many use-cases, it is not good here since you want to control the path that is written.
Since you're already constructing the path with child(authData.uid) you can simply update it with update():
usersref.child(authData.uid).update({3: "paria"});
This will either update the existing value at 3 or write the new value for 3, leaving all other keys under /users/<uid> unmodified.
Alternatively if you want to replace the data that already exists at users/<users>, you can use set() instead of update().
This is all covered in the Firebase JavaScript SDK in the section on storing user data. It is not covered in the AngularFire documentation, since there is nothing specific to Angular about it.

Having trouble converting a complex javascript object to a query string

Here is the javascript object I'm trying to convert to a query string
{$and: [{topic: categoryIds} , {$or :[ {'groups 1': {$ne: ''}}, {groups: $scope.myGroups}]}]};
Basically I'm looking to match a topic that equals a categoryIds and grab documents that have an empty groups array or that the groups array has values and matches one in the array $scope.mygroups
My question is what would be best practice to convert this in an easily parseable format so I can append it to a GET request, and how would you go about parsing it on the express server.
I am using this code in production for querying against a server with a MongoDB backend (using angular and lodash):
.factory('mongoQuery', function() {
return {
fromJson: function(json) {
return JSON.parse(json, fromJsonReviver);
},
toJson: function(object) {
return JSON.stringify(object, toJsonReplacer);
}
};
function fromJsonReviver(key, value) {
var val = value;
if (_.isPlainObject(value)) {
if (_.isNumber(value.$date)) {
val = new Date(0);
val.setUTCMilliseconds(value.$date * 1000);
} else if (_.isString(value.$regexp)) {
var match = /^\/(.*)\/([gimy]*)$/.exec(value.$regexp);
val = new RegExp(match[1], match[2]);
}
}
return val;
}
function toJsonReplacer(key, value) {
var val = value;
if (_.isPlainObject(value)) {
val = _.extend({}, value);
for (var k in value) {
val[k] = toJsonReplacer(k, val[k]);
}
} else if (_.isDate(value)) {
val = {$date: (new Date(value)).valueOf() / 1000};
} else if (_.isRegExp(value)) {
val = {$regexp: value.toString()};
}
return val;
}
})
It includes many of the suggestions mentioned by others in the comments and supports dates and regular expressions.
Other than that, if you need to send the query with a GET request, just use encodeURIComponent like others have mentioned.
Here is a working example: http://plnkr.co/edit/b9wJiUkrHMrDKWFC1Sdd?p=preview
What you're thinking here is basically to redevelop an API server, coupled with some mongodb database, and querying it with some format.
REST is the "best practise" you're looking for. It's a standard that encapsulates some common actions to http ressources.
You should know that you don't need to redevelop an ecosystem based on such a standard. Full-featured REST API servers exist, some are even based on express.js. Loopback and sails.js. These one provide some extra features like
Model abstraction through ORM's, and database-engine agnostism
Automatic REST actions, from database schema or model finition
Advanced querying through "extended REST" ("where", "limit", "order", ...)
Realtime with REST-like websockets
Client side libraries that help you query the server
Some standalone exernal libraries, such as js-data or Restangular can deal with REST server pretty well, and act as a frontend connector to backend
Now, if I had to purely answer your question, and if you realy wanted to go with your solution, I'd just add the mongo query to a where query param on the http call with encodeURIComponent as stated before.

Resources