For loop in coffeescript - ruby-on-rails-3

I am working on rails3.2 and using coffeescript
In my coffeescript i have a for loop and for each , i am executing a API call to fetch results and appending the results to the respective dom
like
for ajaxLink in _ajaxRenderLinks
_template = $(ajaxLink).attr('data-link-template')
apiURL = $(ajaxLink).attr('data-link-url')
console.log($(ajaxLink))
Myapp.API.execute(apiURL, 'get', {}, (data) ->
console.log($(ajaxLink))
if data isnt "" or data isnt undefined
console.log($(ajaxLink))
$(ajaxLink).empty()
$(ajaxLink).append($(HandlebarsTemplates[Myapp.TemplateRoutes.path(_template)](data))))
In the above code, i have two links (one is a link and another is a ul link)
ajaxRenderLinks has these a and ul which has its template to render and the url to fetch the results.
The first console.log prints the first link a and then runs the API call for it and then runs the APi call for it
and then it prints the second link ul and runs the API CALl for it . And finally it tries to append the last result with the second link and not doing the appending for each link, since it ajaxLink inside if data isnt "" or data isnt undefined prints only the second link and not prints the first link and then second link
How to resolve this

Looks like a classic "variable closure in a loop" situation. Because the execute function is asynchronous, it references ajaxLink, which changes as the loop loops. So when execute's callback is invoked, ajaxLink might be something else than what it was when execute itself was invoked.
Try this
for ajaxLink in _ajaxRenderLinks
do (ajaxLink) -> # wrap in an immediately-invoked function
ajaxLink = $(ajaxLink) # save this rather than calling $(...) again and again
_template = ajaxLink.attr('data-link-template')
apiURL = ajaxLink.attr('data-link-url')
Myapp.API.execute(apiURL, 'get', {}, (data) ->
if data? and data isnt ""
ajaxLink.empty().append($(HandlebarsTemplates[Myapp.TemplateRoutes.path(_template)](data))))

Related

Angular is showing undefined for the data but it is working in the view

weatherData;
getDataFromApi(formData) {
this.apiService.getWeather(formData.location).subscribe(data => this.weatherData = data)
console.log(this.weatherData)
}
This is the function to get data and then store it in a local variable weatherData, a JSON file is returned from the API.
To get data in the veiw(HTML) I'm using
<p class="item1">{{ this.weatherData?.request.query }}</p>.
It works fine here but when I need to use the WeatherData for another function then it is showing that the parameters passed is undefined.
The reason is that your code will work asynchronously and the console.log() will be executed before the API call is completed.
The reason that the data is displayed in view is that you subscribed to the data and it will be streamed to the view asynchronously. The view will be updated only after the API call is complete because of subscription. So you can see the data in the view and not in the console.
Try this code and it will work fine.
ngOnInit() {
// getting data for Delhi location
this.apiService.getWeather("Delhi").subscribe(data => {
this.weatherData = data;
console.log(this.weatherData);
});
}
The reason behind undefined was code works asynchronously. While you send the request compiler move to the next line which was console.log(this.weatherData). It print the value of weather data which was undefined when declaring the variable. When response arrive compiler than assign data with this.weatherData.

get request url after AJAX request

I have a search page with link Search?params but any subsequent search requests are made via Ajax forms using Asp.Net. It makes a request to an action with a different name like InstantSearch?params but in the browser I see Search?params.
From this page I have a link to another page and I need to save the Url to return back to this page.
But if I had an AJAX request, Request.Url returns InstantSearch?params, not the link from browser address bar. And the action from this link returns only a Partial View, so when it returns to the previous URL the page is messed up.
How do I get the link of the previous page, from the browser address bar in Asp.Net, not the actual last requested URL?
While searching we are loading masonry containers like this:
$("#main-content-container").load("/Kit/InstantSearch?" + parameters, function() {
$('#mason-container').imagesLoaded(function() {
$('#mason-container').masonry({
itemSelector: '.kit-thumb-container',
columnWidth: 210,
isFitWidth: true,
gutter: 10
});
});
});
Then I'm calling foundation Joyride on same page and need to pass current page URL to return back. Joyride calls onload of the page under this link:
#Html.ActionLink("Go to kit details help", "OrderPageHelp", "Kit", new { returnUrl = Request.Url }, new { #style = "font-size:16px;" })
The needed page return Url is Kit/Search?params, but Request.Url returns that last request when loading masonry with Kit/InstantSearch?params.
How can I pass the needed Url without hard-coding it?
So this ones a bit old but I found myself in a similar situation recently and found a quick work around. Posting it in case any one's interested.
You can solve this problem by taking advantage of the TempData class.
Temp Data can be used to store data in between requests. The information will remain as long as the session is active, until you retrieve the data again.
So when the user first loads the page, before the ajax method is triggered, store the data in a variable on the page AND in the TempData("YourVariableName") object. Create the Action Link with the Saved URL. When the ajax request is fired it will overwrite the value in Request.URL. So, Check for a value in the TempData("YourVariableName"), if it is there, use that value AND Reset the TempData("YourVariableName") value. This will keep the original value of the page URL even after many ajax requests have been triggered. Code in Visual Basic:
#Code
Dim LastURL As String = ""
If Not TempData("LastURL") Is Nothing Then
LastURL = TempData("LastURL")
TempData("LastURL") = LastURL
Else
LastURL = Request.Url.AbsoluteUri
TempData("LastURL") = LastURL
End If
End Code
And pass the value stored in the LastURL variable as a parameter to your action link.

Pass arguments to contact.php

How can I pass variable to contact.php that I can echo on form. I can pass through the form to the email recipient, but, I'm at wits end trying to print to form.
For example, I'd like to set $somevariable="This will be my default Subject", pass the variable through the contact.js and be able in the contact.php receive the variable and use the for the value="#somevaraible" for the subject on the form.
Thanks!
I think you are looking for something like ajax, which will allow you to communicate directly from javascript to PHP scripts. The easiest is probably jquery's implementation of ajax. You are able to pass parameters to your PHP application. https://api.jquery.com/jQuery.ajax/
For example, I can pass any param I want to map.php. With GET this would be the equivalent of calling "map.php?param1=strvalue1&param2=strvalue2" (in the example) I can then capture these values in PHP by using something like $param1 = $_GET['param1']; In the example, whatever the PHP file displays in response to this is then written to an element with the ID of write. All of what I just mentioned can occur after a page has loaded.
You can call the javascript below as many times as you like with whatever javascript functions you see fit. Just keep in mind it will continue to replace whatever is in ID of write, you just need to update that snipplet of code to update the value of your field.
You need to make sure you include Jquery's library when using this like:
<script class="include" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var request = $.ajax({
url: "map.php",
type: "GET",
data:{ param1 : "strvalue1",
param2: "strvalue2"
},
dataType: "html"
});
request.done(function( msg ) {
$( "#write" ).html( msg );
});
</script>

Understanding the "file added" callback

In the following example: https://github.com/blueimp/jQuery-File-Upload/blob/master/basic-plus.html
We can find the following callback:
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('#files');
$.each(data.files, function (index, file) {
var node = $('<p/>')
.append($('<span/>').text(file.name));
if (!index) {
node
.append('<br>')
.append(uploadButton.clone(true).data(data));
}
node.appendTo(data.context);
});
I tried to replicate that code, but can't understand why is there an "each" inside that function, as the callback will be executed once per each uploaded file (so if I'm uploading 3 files at the same time, the callback will be executed 3 times).
So, why is there a need for an "each" loop here? It seems to me that it'll always loop through one element: the uploaded file.
Please help, I'm desperate :(
I think Each loop inside that function is used to append buttons and each file related content Example filename etc....
if you notice the uploadButton has some appended buttonds and click events.

JQuery Tab function not firing via JQuery templates

Hi I'm using JQuery tabs http://jqueryui.com/demos/tabs/ with search results being returned from my server with each row potentially having its own tabs depending on the search results. If the user clicks on the sorting options then the search results change including the tabs within each row returned which may or may not have tabs. In the example above you can see there are 2 records returned and the top record has tabs called Other Videos.
I have been successfully able to retrieve the resultset back from the server and the template is bulding correctly, however i cannot get the .tabs() function to fire? Does anyone have any experience with using tabs and know how I can get my tabs() function to fire?
Here is the code I use to dynamically load the template after the json result set is returned:
$(".searchBox").fadeOut("fast", function () {
$(this).html("").fadeIn("fast", function () {
$("#searchTemplate").tmpl(json.Data.SearchResults.Results).appendTo(".searchBox").fadeIn("fast");
});
});
And here is a for loop that I use to iterate over the results after the template has been loaded with the new html tabs created to try and get the .tabs() function to fire:
for(var i=0;i<json.Data.SearchResults.Results.length;i++){
if (json.Data.SearchResults.Results[i].OtherVideos.length || json.Data.SearchResults.Results[i].VideoFriends.FriendCount > 0)
{
$(document).find("div[id='tabs"+json.Data.SearchResults.Results[i].Counter+"']").tabs();
if ($(document).find("div[id='tabs"+json.Data.SearchResults.Results[i].Counter+"']").length > 0)
alert("it exists");
else
alert("it dont");
}
}
Suffice to say the alert box "it exists" appears successfully so it is finding the dynamically created html tab that the template generated however the tab itself is not being initialized by the statement:
$(document).find("div[id='tabs"+json.Data.SearchResults.Results[i].Counter+"']").tabs();
Does anybody know the reason why or what I'm missing here to get my .tabs() function to fire ...
I've examined the dynamic content and double checked the html code using firebug inspector and everything is according to how it should be the id's are correct, the #id's are there and so on, so my only conclusion is that the .tabs() function is not firing. Is this a limitation on the JQuery tabs itself? Can it not perform this type of "live" loading capability? Is there a callback function I should be using as part of loading the template itself?
Here is a picture of what is being returned after the call to the server without the tabs working:
Okay I fixed the problem, and thought I'd better give my answer for those of you who suffer a similar problem.
I should have placed my for loop inside of the same callback function as the tmpl call e.g:
$(".searchBox").fadeOut("fast", function () {
$(this).html("").fadeIn("fast", function () {
$("#searchTemplate").tmpl(json.Data.SearchResults.Results).appendTo(".searchBox").fadeIn("fast");
// For loop should go here!
});
});
I had the for loop after this block of code and the tabs() function essentially was not referencing the newly created tabs at all.