Derek
Derek

Reputation: 41

Javascript Waiting for result before continuing

I am new to Javascript and trying to run before I can walk but I have to produce a result so here I am.

I thought I had found the answer to this in another question but it did not work for me as expected, below is my script the function of which is to look at a SharePoint list and return some values into 3 arrays, I then use those arrays to provide data to complete some chart data.

                    <script>
                    // load all necessary sharepoint javascript libaries
                    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {

                        // load the sharepoint list.
                        loadSharepointList();
                    });
                    var arrPlan = new Array()
                    var arrActual = new Array()
                    var arrMonth = new Array()


                    // loads the sharepoint list
                    function loadSharepointList() {

                        // create the sharepoint content.
                        var context = SP.ClientContext.get_current();

                        // get the list by the title.
                        var list = context.get_web().get_lists().getByTitle('Package');

                        // create the query.
                        var caml = new SP.CamlQuery();
                        caml.set_viewXml(''); 

                        // get the list items asynchronously
                        var listItems = list.getItems(caml);
                        context.load(listItems , 'Include(Title,Month,Plan,Actual)');
                        context.executeQueryAsync(

                            // success delegate
                            Function.createDelegate(this, function() {

                            // loop through the items.
                                var listEnumerator = listItems.getEnumerator();
                                while (listEnumerator.moveNext()) {

                                    // get the current list item.
                                    var listItem = listEnumerator.get_current();

                                    // get the field value.
                                    var titleValue = listItem.get_item('Month');
                                    var monthValue = listItem.get_item('Month');
                                    var planValue = listItem.get_item('Plan');
                                    var actualValue = listItem.get_item('Actual');
                                    //alert(monthValue);
                                    arrPlan.push(planValue);
                                    arrActual.push(actualValue);
                                    arrMonth.push(monthValue);
                                    //alert(arrMonth);

                                }

                            }),

                            // error delegate
                            Function.createDelegate(this, function() {
                                alert('Error fetching data from Sharepoint!');      
                            }));

                    }

                            //var labels = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October"];
                            var netpphcanvas = document.getElementById("pphchart");
                            var planData = {
                                label: 'Plan',
                                fill: false,
                                data: [1.06,1.58,1.74,1.62,1.50,1.37,1.36,1.44,1.84,1.76],
                                backgroundColor: 'rgba(133, 133, 133, 1)',
                                borderColor: 'rgba(133, 133, 133, 1)',
                                borderWidth: 3,
                                yAxisID: "y-axis-region"
                            };
                            var actualData = {
                                label: 'Actual',
                                fill: false,
                                data: [1.37,1.65,1.84, 1.78,1.55, 1.74,1.57, 1.74,1.90,1.63],
                                backgroundColor: 'rgba(99, 132, 0, 0.6)',
                                borderColor: 'rgba(99, 132, 0, 0.6)',
                                borderWidth: 3,
                                yAxisID: "y-axis-region"
                            };
                            //********This is the part I am using for testing
//***********
                            var netpphData = {
                                //labels: labels,
                                labels: arrMonth,
                                datasets: [planData,actualData]
                                            };
                            var netdelOptions = {
                            scales: {
                                xAxes: [{
                                    barPercentage: 1,
                                    categoryPercentage: 0.6
                                }],
                                yAxes: [{
                                    id: "y-axis-region"
                                }]
                            },
                            elements: {
                                line: {
                                    tension: 0, // disables bezier curves
                                }
                            },
                            title: {
                                display: true,
                                text: 'Net-Delivered PPH',
                                fontSize: 12
                            },
                            legend: {
                                display: true,
                                labels: {
                                    fontColor: '#000',
                                    fontSize: 12
                                }
                            }


                        };

                        var lineChart = new Chart(netpphcanvas, {
                            type: 'line',
                            data: netpphData,
                            options: netdelOptions
                        });
                    </script>

I am attempting to use the returned arrays to complete the Data and labels section of the chart, in order to test this I am starting with the monthly data, which is retrieved in this section of code...

context.executeQueryAsync(

                        // success delegate
                        Function.createDelegate(this, function() {

                        // loop through the items.
                            var listEnumerator = listItems.getEnumerator();
                            while (listEnumerator.moveNext()) {

                                // get the current list item.
                                var listItem = listEnumerator.get_current();

                                // get the field value.
                                var titleValue = listItem.get_item('Month');
                                var monthValue = listItem.get_item('Month');
                                var planValue = listItem.get_item('Plan');
                                var actualValue = listItem.get_item('Actual');
                                //alert(monthValue);
                                arrPlan.push(planValue);
                                arrActual.push(actualValue);
                                arrMonth.push(monthValue);
                                //alert(arrMonth);

                            }

                        }),

I have validated this works using the alert method and it does indeed return the months into the array called arrMonth

however, the rest of the script seems to run before this data source is accessed and the arrMonth is filled.

I have checked this also by using another array called labels and manually filing it and it works correctly.

I thought the reason for this was because the function to get the data was being called Asynchronously

context.executeQueryAsync(

however, I changed this to context.executeQuery( and still got the same result that the page loads before the data are retrieved

Clearly, I have missed something and I would appreciate any help

Kind regards Derek

Upvotes: 2

Views: 638

Answers (1)

rf1234
rf1234

Reputation: 1605

You would need to chain promises to make sure all of this runs in sequence.

These two links will help you:

A synchronous Breeze ExecuteQuery

What does the function then() mean in JavaScript?

And this is a useful tutorial on promise chaining. https://javascript.info/promise-chaining

Upvotes: 1

Related Questions