0

I am writing a jQuery plugin which takes in an array of json files that I then need to compile into one big array.

So far the different parts of the code has work on it's own but once I put it together I am not able to return the new array.

I am assuming it is either me not understanding how to return values from the nested loops or an issue that the $.get() is Asynchronous and the $.each() loops are synchronous. Or likely a mix of both.

I've tried with jQuery $.Deferred but no luck. Any pointers on how to solve this is mostly welcoming.

Here is the plugin code as of now. I've commented the code so it should be 'easy' to see what I am trying to do:

(function ( $ ) {
 
    $.fn.presspull = function( options ) {
 
        // This is the defaults settings which can be changed via the plugin call.
        var settings = $.extend({
            // These are the defaults.
            template	: 	Handlebars.compile( $('#pressTemplate').html() ),
            placeHolder : 	$("#press-grid"),
            addMoreBtn	: 	$("a#press-show-more"),
            segment 	: 	4,
            dataSource 	: 	[]
             
        }, options ); // end settings

        // non mutable elements which can not be changed from the plugin call.
        var cache = {
        		pressArray	: new Array(),
        		compileCount: 0,
        		segmentItt	: 0
        }; // end cache

/*============================================================================
  – Compile Source: function to build and sort the combined press.
==============================================================================*/

        function compileSource() {
        	// check if the data source contains anything.
        	if ( settings.dataSource.length > 0 ) { 
        		// for each json file in the data source do...
	        	$.each( settings.dataSource , function( k, v ) {
	        		// get the data 
	        		$.get( v, function( data, status, xhr ){
	        			// next loop through the output
	        			$.each( data, function( i, e ){
	        				// add each entry to the pressArray
	        				cache.pressArray.push( e );
	        			}); // end each
	        		// once done do..
	        		}).done( function() {
	        			// compile count increments for every data source
						cache.compileCount ++;
						if ( cache.compileCount == settings.dataSource.length ) { 

							cache.pressArray.sort( function( a, b ) {
								var c = new Date(a.date),
									d = new Date(b.date);
					
								return c>d ? -1 : c<d ? 1 : 0;
							}); // end sort

							// after compiling and sorting the new list we return it.

						}; // end if
					// if there is a failure in getting the data it's logged as following     			
	        		}).fail( function() {
    					console.log("Failed to get data from: " + v );
  					}); // end get.done
	        	}); // end each
        	} else {
        		console.log("Source files not found!");
        	};

        	return console.log( cache.pressArray);
        }; // end compileSource

 
    }; // end $.fn.presspull
 
}( jQuery ));

The json files looks as following:

[
      {
            "publication": "Dazed & Confused",
            "date": "2013-05-01",
            "region": "UK",
            "cover": "{{ 'img-press-cover-dazed-2013.png' | asset_url }}",
            "pressmedia": [
                  {
                  "name":"soma",
                  "image": "Document Name 1 - General",
                  "description": "description for image 1",
                  "keyproduct": "link to the key product on the image"
                  },
                  {
                  "name":"soma2222",
                  "image": "Document Name 2 - General",
                  "description": "description for image 1",
                  "keyproduct": "link to the key product on the image"
                  }

            ]

]

And the plugin is called as following:

$().presspull({
      dataSource   :   [
      "http://link/to/external/json/file/01",
      "http://link/to/external/json/file/02",
      "http://link/to/external/json/file/03"
      ]
});

7
  • 2
    To begin with, after the function compileSource() function u may add compileSource(). Second, u may use callback. Commented Apr 6, 2015 at 11:24
  • You can' return value from compileSource as it is asynchronous.... you need to use a callback to process the combined result Commented Apr 6, 2015 at 11:27
  • @Turtle - thank you for the comment. I thought the use of .done() was the callback by using the Promise interface? Commented Apr 6, 2015 at 11:29
  • @ArunPJohny - Thank you for the comment - I might be misunderstanding you but I was under the impression the use of .done() was the callback. If not would you mind pointing me in the direction of where the callback should be added? Commented Apr 6, 2015 at 11:40
  • @SofusGraae stackoverflow.com/questions/14220321/… Commented Apr 6, 2015 at 11:44

1 Answer 1

1

The problem here is your method compileSource is asynchronous which means when you try to return array from the method you ajax contents would not have completed so you will get an empty array.

The solution is to use a callback

    function compileSource(callback) {
        // check if the data source contains anything.
        if ( settings.dataSource.length > 0 ) { 
            // for each json file in the data source do...
            $.each( settings.dataSource , function( k, v ) {
                // get the data 
                $.get( v, function( data, status, xhr ){
                    // next loop through the output
                    $.each( data, function( i, e ){
                        // add each entry to the pressArray
                        cache.pressArray.push( e );
                    }); // end each
                // once done do..
                }).done( function() {
                    // compile count increments for every data source
                    cache.compileCount ++;
                    if ( cache.compileCount == settings.dataSource.length ) { 

                        cache.pressArray.sort( function( a, b ) {
                            var c = new Date(a.date),
                                d = new Date(b.date);

                            return c>d ? -1 : c<d ? 1 : 0;
                        }); // end sort

                        callback(cache.pressArray)

                        // after compiling and sorting the new list we return it.

                    }; // end if
                // if there is a failure in getting the data it's logged as following               
                }).fail( function() {
                    console.log("Failed to get data from: " + v );
                }); // end get.done
            }); // end each
        } else {
            console.log("Source files not found!");
        };
    }; // end compileSource

    //call the compile method
    compileSource(function(array){
        //this function will be called once all the data is received and sorted, the sorted array will be passed as an argument
    })
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.