I just started with Angular and I have an issue with its components and an API call. I have the following content in these files
user.component.html:
<div>
<p>
{{user.name}}
</p>
</div>
user.component.ts:
getUser() {
this.user = this.postService.getPosts();
console.log('TWO');
console.log(this.user);
return false;
}
user.service.ts:
getPosts(){
this.http.get('https://XXXXX/yyy').subscribe(data => {
this.str = data[0];
console.log('ONE');
});
return this.str;
}
The Get response is done correctly and I am able to display the data in the html file ONLY if user is loaded, but the first time that I try to do the request to the API the component.ts finishes its execution before the service, and user is not populated correctly, making the html render empty, so with above code I get this printed in console:
TWO
undefined
ONE
I think if it would be synchronized, it would print:
ONE
John
Two
I found this post but I wasn't able to understand it: Angular - Wait until I receive data before loading template
Can someone please try to help me with this?
Related
I have such url - http://www.coolsite.com/daily-plan/#id=1
What the easiest way to parse that string and read a hash value (the value after #id=)?
Thank you
On client side (i.e. from JavaScript) you can check window.location.hash to get hash. On server side, general answer is 'it is impossible' since hash is not sent in request to server.
Upd: I maybe misunderstood the question. My answer is about how to get hash part of url either in browser or in server side code during request processing, not about string processing.
Upd2: Answer to comment here because it doesn't fit in comment.
How does it work when user clicks on your navigational links?
I assume hash is changed and corresponding content is downloaded via AJAX request from web service or REST.
For example if your user has URL www.example.com in his browser and this page shows a list of product categories. User clicks one category and URL changes to www.example.com/#id=5 and products from that category(with ID=5) are downloaded via AJAX and shown on the page. No postback, only partial page refresh.
Is this close to your scenario?
Now you want user to paste/enter www.example.com/#id=5 directly in the browser address bar and go directly to list of products in that category.
But /#id=5 is not sent to server with request by the browser, so there is no way to get that value on server side, and you can do nothing about it since it is the browser decided not to send this data and you don't have it on server side.
In our project we use solution when server returns only common page code/html, i.e. header, footer, without main/center part of the page. Then there is a JavaScript code which executes right after this common HTML loaded. It takes window.location.hash and sends it to web service via AJAX and web service returns content (HTML) for the main part of the page.
new URI("http://.../abc#xyz").getFragment();
See the Javadocs for URI
Here is how to capture anchor links. Works across all web frameworks.
I'll use an example scenario to illustrate: let's say we need to capture a deep URL http://server.com/#/xyz requested by an unauthenticated user so that they can be redirected to that deep URL post-login.
The unauthenticated user requests http://server.com/#/xyz (everything from the '#' onwards is not sent to the server).
All the server knows is that the user wants http://server.com/ and that they are unauthenticated. Server redirects the user to a login form.
Here's the clever bit: the client is still waiting on their original request so if the server includes a hidden element in the login form with some JS that references window.location.href, it can capture the full URL of the original request complete with the anchor portion:
<form action="/login" method="post">
<div>
<label>Username:</label>
<input type="text" name="username"/><br/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<!-- XXXXXXXXX CLEVER BIT XXXXXXXXXX-->
<script>
document.write('<input type="hidden" name="from" value="'+document.location.href+'"/>');
</script>
<!-- XXXXXXXXXX-->
<div>
<input class="submit-button" type="submit" value="Submit"/>
</div>
</form>
The user authenticates themself and the original URL is sent with the POST. The server can then relay the user to the original deep URL.
String url = " http://www.coolsite.com/daily-plan/#id=1";
int sharpPos = url.indexOf('#');
String q = null;
if (sharpPos >= 0) {
q = url.substring(sharpPos);
}
Surely you can use various methods of string manipulation including regular expressions.
But actually your example is strange. Typically parameters of URL are passed after question mark. In this case you can just use standard class URL:
String q = new URL(" http://www.coolsite.com/daily-plan?id=1").getQuery();
what you are using to do this ?
If you are using jsp or servlet following will be useful to you
if (request.getParameter("#id") == null) {
out.println("Please enter your name.");
} else {
out.println("Hello <b>"+request.getParameter(i)+"</b>!");
}
If you are using javascript for it following function will be useful to you
function getURLParameters()
{
var sURL = window.document.URL.toString();
if (sURL.indexOf("?") > 0)
{
var arrParams = sURL.split("?");
var arrURLParams = arrParams[1].split("&");
var arrParamNames = new Array(arrURLParams.length);
var arrParamValues = new Array(arrURLParams.length);
var i = 0;
for (i=0;i<arrURLParams.length;i++)
{
var sParam = arrURLParams[i].split("=");
arrParamNames[i] = sParam[0];
if (sParam[1] != "")
arrParamValues[i] = unescape(sParam[1]);
else
arrParamValues[i] = "No Value";
}
for (i=0;i<arrURLParams.length;i++)
{
alert(arrParamNames[i]+" = "+ arrParamValues[i]);
}
}
else
{
alert("No parameters.");
}
}
REPLACE the '#' with '?' when parsing the url. Check the code below
String url = "http://www.coolsite.com/daily-plan/#id=1";
String urlNew = url.replace("#", "?");
String id = Uri.parse(urlNew).getQueryParameter("id");
If you URL will the same as you write and doesn't contains anythins else then whis code on Java will help you
String val = "http://www.coolsite.com/daily-plan/#id=1";
System.out.println(val.split("#id")[1]);
Don't forget check to null value.
P.S. If you use servlet you can get this parameter from request.getAttribute("id").
With best regards,
Psycho
if your url get from OAuth callback,then you can't!
because the full url won't send to service because of hash(#)
First of all here's my jsFiddle, so you can see what I'm talking abuout.
I'm using blueimp/jQuery-File-Upload to manage files in the GUI of my asp-net application (server-side code is OK). If I manage the upload one-by-one I am able to upload that file successfully but as I try to submit the whole list the server does not recognize data and get only an empty list.
Here's the piece of code where my issue is:
//initialize fileupload()
$('#fileupload').fileupload({
//I call this function when I add file(s) to the list
add: function (e, data) {
//I do some more actions here
//Then I define this function when the submit button is clicked
$('#submitButton').click(function () {
//fix this?
data.submit();
});
}
)};
So, what am I doing wrong?
Your server should support multipart forms!
A solid handler for ASP.NET is Backload
When a user loads my page for the first time on an iPhone (works fine on Android, IE, FF,
Opera, Chrome, Safari), the two portions of the page generated by a Prototype/Scriptaculous Ajax.Updater call are garbled - they look as if a binary file were injected into the page or the character map was scrambled. If the user then reloads the page, or uses the page's tabs to navigate around via Ajax.Updater requests, everything is then fine. It's only the very first time the page is loaded in a browser session that this occurs. Here are the relevant calls with a bit of context:
soundManager.onready(function(){
new Ajax.Updater('PlayerSet', 'http://' + location.host +
playerHTMLloc, {method: 'post', onComplete: startPlayer});
});
This is only called once per site visit (so the user has to reload in order to get it to display correctly). It calls a python script that writes html to stdout.
Here's the other:
show: function(elm) {
var id = elm.identify();
elm.addClassName(id.sub('-html', '-selected'));
var link = 'ajax/' + id.sub('-', '.');
$('centercontent').update('<div id="floaterForSpinner"></div><div
id="centerSpinner"><img src="images/ajax-loader.gif"></div>');
new Ajax.Updater('centercontent', link, {evalScripts: 'true',
method: 'post'});
}
This is part of a small class that handles tabs on the page. Again, only the first time show() is called does the error occur. After that the tabber works normally. The updater is just pulling html text files from the server.
The issue occurs with both Prototype/Scripty 1.6.1/1.8.3 and 1.7/1.9.0.
The post and receive headers are identical for the first and subsequent loads, and the acceptable charset is Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7 in all cases per Firebug.
I don't have an iPhone myself, and none of the off or online iPhone simulators I've tried reproduce the problem, so testing this is going to be a nightmare. Hence, anything anyone could do to help, would be, uh, very... helpful.
UPDATE based on questions I received on the GG prototype list:
All the code above is called after the DOM is loaded:
document.observe('dom:loaded', function() {
Ajax.Responders.register({onCreate: removeListeners});
Ajax.Responders.register({onComplete: postAJAX});
new Lightbox();
initMailList();
AT = new AjaxTabber('tablist');
initInternalLinkListener();
initIE6msgClose();
$('PlayerSet').update('<div style="text-align:center">
<img src="images/ajax-loader.gif"></div>');
soundManager.onready(function(){
new Ajax.Updater('PlayerSet', 'http://' + location.host +
playerHTMLloc, {method: 'post', onComplete: startPlayer});
});
});
AjaxTabber is the tab class that contains the show() function I mentioned earlier. The document.observe function above is in the last js file in the header.
UPDATE #2:
Replacing
document.observe('dom:loaded', function() {
with
Event.observe(window, 'load', function() {
in the 3rd code block fixes the garbled loads. However, the fix raises new questions/issues:
Why do the Ajax.Updater loads need to have the entire page loaded to work correctly? A DOM load should be all that's necessary. There's no reason to need the images loaded for an ajax load to work.
My overall page performance is now substantially degraded to fix an iPhone only problem. I'd really like to go back to loading once the DOM load is complete.
Calling update() and then Ajax.Updater on the same element one after another like this might introduce timing problems that can be difficult to diagnose. I recommend doing this instead (to add a "loading" indicator to your Ajax-loading element):
new Ajax.Updater('elementID', '/path/to/server', {
parameters: {},
method: 'get',
onCreate: function(){
$('elementID').update('placeholder html here');
},
onSuccess: function(){
// any other cleanup here
}
});
The onCreate callback hook will guarantee to run and complete before the request is sent and the element is updated by A.U.
I am new in extjs. I need to know how to make ajax call in extjs and display the json values in inside div. I don't need to use grid..
In ExtJS, you will have to use the Ext.Ajax class to make ajax calls to a remote server. Following is a typical code showing how to do it:
Ext.Ajax.request({
url: 'ajax_demo/sample.json',
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
console.dir(obj);
},
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
}
});
In case of HTTP success (200 OK), the control will go inside the success callback and the first things that we have to do is decode the response.responseText which will give you the JSON response coming from the back-end data source.
Once you have code the JSON, you are free to format it and add it to any element (say to a div in your case). In case you want to format the JSON data nicely before adding, you may do that using Template/XTemplate.
I have used something like this.
$.getJSON('somepathtoserver/somefile.php?callback?', variable,function(res){
});
In the somefile.php, I have a callback function that processes and return the value to the js function.
like this:
{
echo $_GET['callback']. '(' . "{'someValue' : $calculatedVariable}" . ')';
}
This is tricky, but very useful when trying to ajax from one server to a different server, which is the reason I would use JSON here and not just a straight AJAX request.
I'm working on an application using ASP.NET 4.0 and MVC 2.0. If it's in any way relevant, I'm using VS2010.
I'm running into complications with TempData. I did not write the original code, but it isn't working correctly and I'm attempting to fix it. I don't have a lot of experience working with TempData and ViewData.
I have an Index action as follows (pseudocode):
public virtual ActionResult Index()
{
var vm = new IndexViewModel();
// some code here to set up the ViewModel
if (TempData.ContainsKey("Success"))
vm.Success = true;
return View(MVC.Controller.Views.Index, vm);
}
And I have a POST action as follows (pseudocode):
[HttpPost]
public virtual ActionResult Index(IndexViewModel vm, List<int> formData)
{
if (DoSomethingWithData(formData))
{
TempData["Success"] = true;
return RedirectToAction(MVC.Controller.ActionNames.Index);
}
TempData["Message"] = "Failed to use formData";
return View(MVC.Controller.Views.Index, vm);
}
The view emits a form and prefaces it with a success message if vm.Success is true. It will also emit the message in TempData["Message"] if it is present.
The first time I come to the page I get just the form. I enter INVALID form data and submit it... and I get the form prefaced by the error message as expected. (I know there's poor design here since it doesn't redirect... and you get poor user experience with refresh, etc. but I'm not worried about that yet) This is all great.
The problem manifests when I use VALID form data. If I submit valid form data, I get the page back prefaced with a success message as expected, but if I refresh the page the success message is still there. Indeed if I go to a completely different part of the site and navigate back, the success message is still there. For some reason after a redirect and read, the tempdata is still there. There has been both a redirect and a read... shouldn't the temp data now be clear?
I'm reasonably certain that the other places I navigate to aren't setting TempData["Success"] for any reason, but to be sure I've navigated to things like Google, and come back directly to the URL for this page, and it still seems as though TempData["Success"] is populated.
It's very clear that either I don't clearly understand how TempData is supposed to function (unsurprising) or something unusual is happening that I simply don't have the experience to see.
Any advice is welcome!
Thanks,
Dave
[EDIT]
The view doesn't actually emit the form when there's a success message... it only emits the success message.
The view looks more or less like this:
<% if (TempData.ContainsKey("Message")) { %>
Emit message...
<% } %>
<% using (Html.BeginForm(MVC.Controller.ActionNames.Index,
MVC.Controller.Name,
FormMethod.Post,
new { id = "form"})) { %>
<% if (!Model.Success) { %>
Emit form...
<% } else { %>
Emit confirmation message...
<% } %>
<% } %>
Francisco pointed me towards something I hadn't considered... but it turns out the constructor for the viewmodel sets Success to false... so it's not something odd with that. I know for sure that TempData["Success"] is still set (rather than something like foolishly reusing a viewmodel with success set to true) because I've stepped through the code and it continually steps into that if statement where it sets vm.success = true, even after a refresh.
Microsoft has made a change to the behavior of TempData that we need to be aware of in MVC 2 and 3. TempData now no longer completely clears at the end of a controller action cycle. TempData can now (automatically and without you changing anything) persist through to other pages. TempData keys are now only cleared if they’ve been read. Furthermore, if you use RedirectResult or RedirectToRouteResult, they will persist even if they are read.
Here are more details: warning-mvc-nets-tempdata-now-persists-across-screens
Just adding this as I said in my comment. I suggest to do
if (TempData["Success"] != null)
vm.Success = true;
Instead of
if (TempData.ContainsKey("Success"))
vm.Success = true;
... so it counts as a TempData read. Glad it worked.
Regards