How can I get window.location.href in Elm? - elm

I have an index.html which contains my Elm app. The Elm app uses various GETs to an API served by the same server as the one that serves the index.html.
Rather than hardcode the URLs in my Elm code for the GETs, e.g.:
url =
"http://localhost:8080/api/tasks"
is there a function which returns the value of window.location.href?
I'd like to do something like:
url =
getHref() ++ "/api/tasks"
In this way, if I move my server to somewhere else I will not need to update all the urls in my Elm code.

Whilst the above answers your question, I think there is a more straightforward solution to the problem:
If the application code is being served from the same server (URL) as the API you want to access you don't need to specify the server - just the root relative path for your api i.e. you can make requests to /api/tasks from your elm code and the browser will sort out the rest for you.
This is how I addressed the problem in my deployed code.

There is elm-history package with the location function for this, but it's deprecated and doesn't exist for 0.18 version.
Then you might want to use elm-navigation package and explicitly store the current location in your model.
Please have a look at this example. A program with navigation can be created via:
Navigation.program UrlChange
{ init = init
, view = view
, update = update
, subscriptions = (\_ -> Sub.none)
}
UrlChange here is a type of message, which triggers on every url change, so you can process it and set the current location:
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
UrlChange location ->
( { model | location = location }
, Cmd.none
)
And then purely get the location.href wherever the model is accessible.
In the provided application, this place is view: viewLocation model.location
In your application, it's, for example, something like this:
url model =
model.location.href ++ "/api/tasks"

Use URL Builder to link to anoter page on your site
There's no need to specify the base url:
import Url.Builder exposing (absolute)
url = absolute [ "api", "tasks" ] []
-- results in "http://localhost:8080/api/tasks"
-- if working in your developer environment
-- the URL will automatically change in production
-- to the correct URL assuming you don't have any crazy set ups
And you definitely will not need to worry if your server URL changes. So you can easily switch from a development to production/staging environments without any additional configuration.

Related

How to detect browser in Elm

How do I detect the browser from Elm?
Specifically I want to be able to tell if the web app is running on a tablet (Safari on iPad, etc.) or not.
You can use Html.programWithFlags to pass information from Javascript to Elm on initialization.
Assuming you can infer browser from user agent, you could do something like this:
type alias Flags =
{ userAgent : String }
Your init would look like this:
init : Flags -> ( Model, Cmd Msg )
init flags =
...
main =
programWithFlags { init = init, ... }
And from Javascript, you would pass the flags in like this:
var app = Elm.Main.fullscreen({
userAgent: navigator.userAgent
});
Side note: User agent may not be enough to fully detect browser. You can see this StackOverflow answer which provides more reliable detection. Either way, the end result is that you would send some kind of flag along to the Elm app on init.
More info on Flags can be found here.
You can use elm-vendor package.
http://package.elm-lang.org/packages/coreytrampe/elm-vendor/latest

Issue in getting iteration data from rally API

I am using following url to get the iteration data from rally.
I then parse the json data received.
def query = URLEncoder.encode("(Project.Name contains \"1 Prime Infrastructure\")", "UTF-8")
def rallyURL = "https://us1.rallydev.com/slm/webservice/v2.0/iteration?query="+query+"&fetch=true&start=1&pagesize=200"
The issue is it giving 0 records. But when i change the name to some other project the data comes.
Probably it is because of the default workspace for my username and password. I want project data from different workspace.
I have access to all this workspace.
can someone tell how to set the workspace before making an api call so that i can get the iteration data ??
Thanks,
You can simply include a workspace parameter in your url to override the default:
&workspace=/workspace/12345
You can also always further refine your results to a specific project:
&project=/project/12345
Or to a specific hierarchy:
&projectScopeUp=true
&projectScopeDown=true

acessing data from another model using remote hooks in loopback

I am using loopback in c9 ,basically i have 2 models
->file(that uploads a file )
->user(that has a remote method that updates values fetched from client )
I want to upload the file first and get the uploaded filename as it ll be used by the remote method to be updated in db(monodb).How can I access filename property in file model in user model without model relations. I tried the below code in "user.js"
`var loopback=require('loopback');
var file=loopback.getModel('file');
console.log(file.name);`
but it displays only "undefined".Is it wrong ?if so what's the way to access the filename ??
or should I use hooks?
The upload logic does not seem very clear to me, but if the question is exactly what you ask and is about accessing one model from another model in a remote hook, then you may find the answer here: Loopback documentation: Getting a reference to a model in JavaScript
To be more precise, in your user.js you may have something like this:
module.exports = function(User) {
User.beforeRemote('**', function(ctx, unused, next) {
var File = User.app.models.File;
...
});
}

Balanced Payments doesn't seem to work with Phonegap

We are not able to call balanced.card.create from a Phonegap application. This is reproduced in a stock Phonegap application here: https://github.com/kevg/phonegap-balanced. Full details are in the README.md on github, but the basic summary is:
For those not familiar with phonegap, the main page that loads is
index.html. This initializes phonegap in index.js. When the device is
ready, we will show a hidden DIV with a button named "Execute
Balanced." When you click this button, app.executeBalanced in index.js
will be called which prompts for the balanced marketplace URI, loads
balanced.js with $.getScript, and then calls balanced.card.create with
a test credit card.
The expected result is that callbackHandler is called or an exception
is caught. Instead, it seems the execution of the Javascript thread
disappears into balanced.card.create, never to return and without any
error.
Alrighty, I found the bug in balanced.js. So, in Phonegap, window.location.href returns something like file:///.../index.html. Balanced.js creates an iframe to something like https://js.balancedpayments.com/proxy#file
var src = proxy + "#" + encodeURIComponent(window.location.href);
https://github.com/balanced/balanced-js/blob/master/src/utils.js#L48
In the script returned in proxy.html (which I can't find on github), it does:
c.parentURL=decodeURIComponent(
window.location.hash.replace(/^#/,"")
).replace(/#.*$/,"")
c.parentDomain=c.parentURL.replace(/([^:]+:\/\/[^\/]+).*/,"$1")
The regex doesn't match because file: has three slashes. Now, at first, I thought I could just convert the regex to:
/([^:]+:\/+[^\/]+).*/
However, then there's another problem, because balanced does a security origin check on the match:
if (d.origin.toLowerCase() !== c.toLowerCase()) return !1;
However, the regex returns file:///firstcomponent, whereas event.origin does not include a host name for the file scheme, so these won't match even with a fixed regex.
I can't change anything in the script returned in the proxy response because if I load that from a domain other than balancedpayments.com, then the AJAX POST fails (return code 0 with a blank body). Therefore, the only thing I can control is the hash passed to the iframe.
However, since this regex is a replace, we can simply pass exactly what we know we need (we don't care that the regex is a no-op).
Therefore, the solution is to change L48 above to:
var src = proxy + "#" + encodeURIComponent("file://");
This works.

Getting Path (context root) to the Application in Restlet

I am needing to get the application root within a Restlet resource class (it extends ServerResource). My end goal is trying to return a full explicit path to another Resource.
I am currently using getRequest().getResourceRef().getPath() and this almost gets me what I need. This does not return the full URL (like http://example.com/app), it returns to me /resourceName. So two problems I'm having with that, one is it is missing the schema (the http or https part) and server name, the other is it does not return where the application has been mounted to.
So given a person resource at 'http://dev.example.com/app_name/person', I would like to find a way to get back 'http://dev.example.com/app_name'.
I am using Restlet 2.0 RC3 and deploying it to GAE.
It looks like getRequest().getRootRef().toString() gives me what I want. I tried using a combination of method calls of getRequest().getRootRef() (like getPath or getRelativePart) but either they gave me something I didn't want or null.
Just get the base url from service context, then share it with the resources and add resource path if needed.
MyServlet.init():
String contextPath = getServletContext().getContextPath();
getApplication().getContext().getAttributes().put("contextPath", contextPath);
MyResource:
String contextPath = getContext().getAttributes().get("contextPath");
request.getRootRef() or request.getHostRef()?
The servlet's context is accessible from the restlet's application:
org.restlet.Application app = org.restlet.Application.getCurrent();
javax.servlet.ServletContext ctx = ((javax.servlet.ServletContext) app.getContext().getAttributes().get("org.restlet.ext.servlet.ServletContext"));
String path = ctx.getResource("").toString();