I'm using the Atmosphere plugin in a Grails application to make Ajax push calls to the client. The basic architecture is, I have a loop in the server which creates the data that I want to push to the browser, so in every iteration it uses the atmosphere broadcast() method to send the data to the client.
It works fine when I use it outside the loop, like this:
def builder = new JSONBuilder()
def jsonResult = builder.build{
artist = "incubus"
location = {
lat = 45.678909
lng = -14.45667
}
}
broadcaster['/atmosphere/recommend'].broadcast(jsonResult)
However, when I use it programmatically inside the loop, the browser throws the error: An invalid or illegal string was specified" code: "12, and doesn't work properly.
A simplified example of the loop is as follows:
[[lat:45.678909,lng:-14.45667],[lat:32.56433,lng:22.4566]].each{
def builder = new JSONBuilder()
def jsonResult = builder.build{
artist = "incubus"
location = {
lat = '"${it.lat}"'
lng = '"${it.lng}"'
}
}
broadcaster['/atmosphere/recommend'].broadcast(jsonResult)
}
Any ideas why is this happening?
Thanks!
I think it should work, if you remove the quotes.
location = {
lat = it.lat
lng = it.lng
}
Christian
Related
I'm trying to do a simple count check for a customer to see if they need to add a source before moving onto another page. However, my calls to the STPCustomer object's attributes are not matching the information for the full response.
I've tried clearing the customer cache and reloading the customer, but uh... still no match.
Here's a truncated like, essentials code. The class has the STPPaymentContextDelegate attached.
private var customerContext = STPCustomerContext?
private var paymentContext = STPPaymentContext?
func setupStripe() {
self.paymentContext = STPPaymentContext(customerContext: self.customerContext!)
self.paymentContext?.hostViewController = self
self.paymentContext?.delegate = self
self.paymentView = STPPaymentMethodsViewController(configuration: STPPaymentConfiguration.shared(), theme: STPTheme.default(), customerContext: self.customerContext!, delegate: self)
}
func getCustomerSources() {
if let customer = customerContext.retrieveCustomer({ (customer, error) in
if customer != nil {
print(customer.sources.count)
print(customer.sources)
print(customer.allResponseFields)
}
})
}
When I run getCustomerSources() on the test customer, I am expecting:
1
[ba_1Dvf46LrBVaGM6Sq9qIYhOlJ]
AnyHashable("id"): cus_number, AnyHashable("email"): rosa_diaz#gmail.com, AnyHashable("default_source"): ba_1Dvf46LrBVaGM6Sq9qIYhOlJ, AnyHashable("created"): 1548220659, AnyHashable("description"): LiG8WbVhT8SVhta8LdfUuWzOwQn2, AnyHashable("livemode"): 0, AnyHashable("object"): customer, AnyHashable("sources"): {
data = (
{
"bank_name" = "STRIPE TEST BANK";
country = US;
currency = usd;
customer = "cus_EOQzwwGPjzopjS";
fingerprint = 1AQMB9nzeGSGXHst;
id = "ba_1Dvf46LrBVaGM6Sq9qIYhOlJ";
last4 = 6789;
metadata = {
};
object = "bank_account";
"routing_number" = 110000000;
status = verified;
}
);
"has_more" = 0;
object = list;
"total_count" = 1;
url = "/v1/customers/cus_EOQzwwGPjzopjS/sources";
}])
However, instead of my 1 and ba_1Dvf46LrBVaGM6Sq9qIYhOlJ, I am getting 0 and []. But the allResponseFields section is the same.
Any ideas as to why there's a discrepancy between what the STPCustomer object attributes are returning and what the actual response is telling me?
it's hard to say what's going on without knowing more about the error parameter that your callback receives. It sounds like there might be an error parsing the API response, and printing the error passed into your retrieveCustomer block should give you a better idea about what's going on. If the error persists I'd recommend contacting support#stripe.com with details, as they can help directly with iOS app questions!
I get a bunch of different URL from my sources and what I would like is to redirect to the same URL, but with campaign data added to URL (to track the referred clicks).
For example I have these URLs:
www.example.com/category/product/name.html
www.example.com/id_product=5
I want to add at the end the following: utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
And the URLs to become
www.example.com/category/product/name.html?utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
www.example.com/id_product=5&utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
How to I correctly check and cover all the cases if a URL string has parameters, and add mine?
I want to do it in node.js
Thank you
Elaborating on #snkashis, a similar but arguably more elegant solution, again using node's url module, is:
var addQueryParams = function (cleanUrl) {
var obj = url.parse(cleanUrl, true, false);
obj.query['utm_source'] = 'SOURCE';
obj.query['utm_medium'] = 'MEDIUM';
obj.query['utm_campaign'] = 'CAMPAIGN';
delete obj.search; // this makes format compose the search string out of the query object
var trackedUrl = url.format(obj);
return trackedUrl;
};
This works, because url.format first looks for search and, if it can't find it, it composes the query string from the query object
(taken from node url module documentation http://nodejs.org/api/url.html#url_url_format_urlobj )
search will be used in place of query
query (object; see querystring) will only be used if search is absent.
Here is a example showing different scenarios using Node's URL module.
var url = require('url');
var exurls = ["www.example.com/category/product/name.html","www.example.com/id_product=5?hasparam=yes"]
var to_append = "utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN";
for (i=0;i<exurls.length;i++) {
var parsedobj = url.parse(exurls[i],true,false);
//Below checks if param obj is empty.
if (Object.keys(parsedobj.query).length!==0) {
var newpath = parsedobj.href+"&"+to_append;
}
else {
var newpath = parsedobj.href+"?"+to_append;
}
console.log(newpath);
}
Connect will help you:
var connect = require('connect');
var app = connect();
app.use(connect.query());
app.use(function (req, res, next) {
console.log(req.query);
res.end(JSON.stringify(req.query));
});
app.listen(3000);
Is there some function in TweetSharp that could be used in a similar way to my 'IsFollowingMe' below?
I'd like to check whether a user is following me before I attempt to send some private message.
TweetSharp.TwitterService service;
string screenName = "#some_one";
string someMessage = "Some Message";
if (service.IsFollowingMe(screenName))
{
service.SendDirectMessage(screenName, someMessage);
else
NotifyThatSendingNotPossible();
}
First option to such approach is to use:
TweetSharp.TwitterService service;
TwitterCursorList<TwitterUser> followers = service.ListFollowers();
and then iterate through the result to find out if user is following my account. But this will eventually be ineffective when there are a lot of followers.
Another option is to execute service.SendDirectMessage and then check if the result is null or not. I tested such approach with success - however my application logic prefers to check in advance if sending is possible and based on this information should do different actions.
The answer is as follows:
TweetSharp.TwitterService service;
string fromUser = "#mr_sender";
string toUser = "#some_one";
string someMessage = "Some Message";
TweetSharp.TwitterFriendship friendship =
service.GetFriendshipInfo(fromUser, toUser);
if (friendship.Relationship.Source.CanDirectMessage.HasValue &&
friendship.Relationship.Source.CanDirectMessage.Value)
{
service.SendDirectMessage(screenName, someMessage);
}
else
{
NotifyThatSendingNotPossible();
}
I could able to solve this using below way.
var twitterFriendship = service.GetFriendshipInfo(new GetFriendshipInfoOptions() { SourceScreenName = "source_name", TargetScreenName = "target_name"});
After that, you can check like below
if(twitterFriendship.Relationship.Source.Following && twitterFriendship.Relationship.Target.FollowedBy)
{
service.SendDirectMessage(new SendDirectMessageOptions() { ScreenName="target_name",Text="message"})
}
I'm creating a Grails application which makes use of the Atmosphere plugin to push data to the browser. However I'm having trouble in creating a broadcast channel to a single user (the session's user). My code is has follows:
Service:
static atmosphere = [mapping: '/atmosphere/recommend']
def onRequest = { event ->
def request = event.request
def response = event.response
event.suspend()
def broadcaster = event.broadcaster
request.session.broadcaster = broadcaster
broadcaster.broadcasterConfig.addFilter(new XSSHtmlFilter())
}
def onStateChange = { event ->
if (!event.message) return
event.resource.response.writer.with {
write "<script>parent.callback('${event.message}');</script>"
flush()
}
}
Controller:
def builder = new JSONBuilder()
def jsonResult = builder.build{
artist = artistInstance
location = {
lat = eventInstance.location.lat
lng = eventInstance.location.lng
}
}
session.broadcaster.broadcast(jsonResult)
This solution broadcasts the jsonResult to every user. What I want to achieve is to broadcast only for the current user.
Any ideas?
If you need more details just let me know.
Thanks
I thinks you can use session to share the onRequest's event.
request.session[userId]=event
then in controller :
broadcast(jsonResult,session[userId])
When you define your events in grails, you can filter out cients by using a browserFilter closure.
Hey you can make use of the uuid which is assigned to each Atmosphere Resource.
To retrieve the suspended uuid based on an Atmosphere Request you can do:
String suspendedUUID = (String)req.getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
You can pass the session
session.broadcaster.broadcast(jsonResult, AtmosphereResource)
See this API.
(I am Atmosphere's creator).
I am trying to generate the OData Proxy for the service : http://services.odata.org/Northwind/Northwind.svc/$metadata
I am using System.Data.Services.Design.EntityClassGenerator for generating the OData proxy.
When I instantiate the EntityClassGenerator and call GenerateCode the output has no errors. But there is no code in the generated proxy code.
The same code works for my own service. But when I point it to any external service the EntityClassGenerator is not working.
Here is the code :
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(metadataEndpoint);
webRequest.Method = "GET";
webRequest.ContentType = "text/xml;encoding='utf-8";
webRequest.Proxy = (proxy != null) ? proxy : WebRequest.DefaultWebProxy;
using (WebResponse response = webRequest.GetResponse())
{
string xml = string.Empty;
XmlReaderSettings settings = new XmlReaderSettings();
using (TextReader reader = new StreamReader(response.GetResponseStream()))
{
xml = reader.ReadToEnd();
using (XmlTextReader sourceReader = new XmlTextReader(reader))
{
using (StringWriter targetWriter = new StringWriter())
{
// Generate the OData End point proxy.
EntityClassGenerator entityGenerator = new EntityClassGenerator(LanguageOption.GenerateCSharpCode);
entityGenerator.OnPropertyGenerated += new EventHandler<PropertyGeneratedEventArgs>(entityGenerator_OnPropertyGenerated);
IList<System.Data.Metadata.Edm.EdmSchemaError> errors = entityGenerator.GenerateCode(sourceReader, targetWriter, namespacename);
entityGenerator.OnPropertyGenerated -= new EventHandler<PropertyGeneratedEventArgs>(entityGenerator_OnPropertyGenerated);
odataProxyCode = targetWriter.ToString();
}
}
}
}
I found the code in the question to be a useful starting point for doing exactly what the OP was asking. So even though the OP doesn't accept answers, I'll describe the changes I made to get it to work in case it is useful to someone else.
Removed the xml = reader.ReadToEnd(); call. I assume that was for debugging purposes to look at the response from the web request, but it had the result of "emptying" the reader object of the response. That meant that there was nothing left in the reader for the GenerateCode call.
The important one: Changed the use of EntityClassGenerator to System.Data.Services.Design.EntityClassGenerator. In the code below, I included the entire name space for clarity and specificity. Based on the code in the question, it appears the OP was probably using System.Data.Entity.Design.EntityClassGenerator. I used .NET Reflector to examine datasvcutil.exe, which is a command-line utility that can generate the proxy classes. I saw that it referenced the generator in that other name space.
For figuring out the problems, I dumped the errors from the GenerateCode call. One could examine them in the debugger, but some kind of automated checking of them would be needed regardless.
Here is what I ended up with:
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.
Create("http://services.odata.org/Northwind/Northwind.svc/$metadata");
webRequest.Method = "GET";
webRequest.ContentType = "text/xml;encoding='utf-8";
webRequest.Proxy = WebRequest.DefaultWebProxy;
using (WebResponse response = webRequest.GetResponse())
{
using (TextReader reader = new StreamReader(response.GetResponseStream()))
{
using (XmlTextReader sourceReader = new XmlTextReader(reader))
{
using (StringWriter targetWriter = new StringWriter())
{
// Generate the OData End point proxy.
System.Data.Services.Design.EntityClassGenerator entityGenerator =
new System.Data.Services.Design.EntityClassGenerator(
System.Data.Services.Design.LanguageOption.GenerateCSharpCode);
IList<System.Data.Metadata.Edm.EdmSchemaError> errors =
entityGenerator.GenerateCode(sourceReader, targetWriter,
"My.Model.Entities");
foreach (System.Data.Metadata.Edm.EdmSchemaError error in errors)
Console.WriteLine("{0}: {1}", error.Severity.ToString(), error.Message);
string odataProxyCode = targetWriter.ToString();
}
}
}
}