<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="CACHE-CONTROL" content="NO-CACHE"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Loading external data through HTTPService</title><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"><link rel="stylesheet" href="/css/styles.css"><link rel="shortcut icon" href="/img/favicon.ico"></head><body class="page post" id="main"><header class="docs-header"><div class="container"><div class="topbar"><div class="topbar-left"><a href="/"><span class="site-title">Apache Royale</span></a></div><div class="topbar-center"></div><div class="topbar-right"><button class="topMenu-dropbtn"><i class="fa fa-bars"></i>&nbsp;Menu</button><ul class="topMenu"><li><a href="/features">Features</a></li><li><a href="https://apache.github.io/royale-docs/get-started">Get Started</a></li><li><a href="/download">Download</a></li><li><a href="/docs">Docs</a></li><li><a href="/blog">Blog</a></li><li><a href="https://github.com/apache/royale-asjs/wiki/Apache-Royale-Source-Code-Repositories"><i class="fa fa-github"></i> GitHub</a></li></ul></div></div><div class="post-header"><h1>Loading external data through HTTPService</h1><div class="post-meta">by Carlos Rovira on September 23, 2018</div></div></div></header><div class="page-content"><div class="container"><article><p>This example shows you how to use <strong>HTTPService</strong> to access external data to use in your Apache Royale application.</p><p>You can use HTTPService to retrieve data in XML, JSON, or other formats. We'll use Github API services to get JSON formatted GitHub data so we can load info about the code of this example, which is hosted in GitHub.</p><p>It uses the new Jewel UI set that supports themes and is available in <a href="https://royale.apache.org/download/">the 0.9.4 release or later</a>.</p><pre><code class="language-mxml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;j:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
              xmlns:j=&quot;library://ns.apache.org/royale/jewel&quot;
              xmlns:js=&quot;library://ns.apache.org/royale/basic&quot;
              xmlns:html=&quot;library://ns.apache.org/royale/html&quot;
              xmlns:services=&quot;services.*&quot;&gt;

    &lt;fx:Script&gt;
        &lt;![CDATA[
           import org.apache.royale.events.Event;
           import org.apache.royale.events.MouseEvent;
           import org.apache.royale.jewel.Alert;

           public function getGithubContent(event:MouseEvent):void
           {
               service.getContent();
           }
           
           public function dataReadyHandler(event:Event):void
            {
               Alert.show(service.jsonToString, &quot;JSON data retrieved&quot;);
               jsonData.html = &quot;Some JSON Data: &lt;br&gt;&lt;strong&gt; - service.json.name:&lt;/strong&gt; &quot; + service.json.name + 
                                &quot;&lt;br&gt;&lt;strong&gt; - service.json.sha:&lt;/strong&gt; &quot; + service.json.sha +
                                &quot;&lt;br&gt;&lt;strong&gt; - service.json._links.html&lt;/strong&gt; &quot; + service.json._links.html;
                sourceCodeMXMLText.text =  service.sourceCode;
            }
        ]]&gt;
    &lt;/fx:Script&gt;
    
    &lt;fx:Declarations&gt;
        &lt;services:GitHubService id=&quot;service&quot; 
           sourceCodeUrl=&quot;https://api.github.com/repos/apache/royale-asjs/contents/examples/blog/BE0011_Loading_external_data_through_HTTPService/src/main/royale/BE0011_Loading_external_data_through_HTTPService.mxml&quot;
           dataReady=&quot;dataReadyHandler(event)&quot;/&gt; 
    &lt;/fx:Declarations&gt;

    &lt;j:initialView&gt;
        &lt;j:View&gt;
            &lt;j:beads&gt;
                &lt;j:HorizontalCenteredLayout/&gt;
            &lt;/j:beads&gt;

            &lt;j:Card percentWidth=&quot;90&quot;&gt;
                &lt;html:H3 text=&quot;Loading Github external data through HTTPService&quot;/&gt;
                
                &lt;j:Label text=&quot;This example loads its source code in the text code panel:&quot;/&gt;

                 &lt;html:Pre height=&quot;300&quot; percentWidth=&quot;100&quot; style=&quot;background-color: white&quot;&gt;
                    &lt;html:beads&gt;
                        &lt;j:ScrollingViewport/&gt;
                    &lt;/html:beads&gt;
                    &lt;html:Code id=&quot;sourceCodeMXMLText&quot;/&gt;
                &lt;/html:Pre&gt;
                
                &lt;j:Label id=&quot;jsonData&quot; multiline=&quot;true&quot; html=&quot;This label shows JSON data when loaded.&quot;/&gt;

                &lt;j:Button text=&quot;Retrieve source code from Github&quot; emphasis=&quot;primary&quot; click=&quot;getGithubContent(event)&quot;/&gt;
             &lt;/j:Card&gt;
        &lt;/j:View&gt;
    &lt;/j:initialView&gt;
&lt;/j:Application&gt;
</code></pre><p>We create an Apache Royale interface that shows a text code panel to load the source code of this example in it. Github doesn't let us load a page from its domain in an iFrame, so this is the only way to embed GitHub content in your application.</p><p>The text code panel is made of <em>pre</em> and <em>code</em> html tags with some custom style to make the background white. We provide a Label to show accessing Json data directly with dot notation. Finally we provide a button to trigger the <strong>HTTPService</strong>.</p><blockquote><p><strong>Tip:</strong> We use the <strong>ScrollingViewport</strong> bead to add scrolling behavior to our text code panel.</p></blockquote><p>The most important piece in this example is the custom <strong>GitHubService</strong> class that wraps the HTTPService object. We declare it in MXML in our application to pass the Github URL to request and declare an event handler to show the data once it is loaded.</p><p>This is the <strong>GitHubService</strong> class:</p><pre><code class="language-as3">package services
{
    import org.apache.royale.events.Event;
    import org.apache.royale.events.EventDispatcher;
    import org.apache.royale.net.HTTPConstants;
    import org.apache.royale.net.HTTPService;
    import org.apache.royale.utils.string.Base64;

    [Event(name=&quot;dataReady&quot;, type=&quot;org.apache.royale.events.Event&quot;)]
    /**
     * GitHubService is in charge of getting the source code of some example
     * so we can show the code in a TabBarContentPanel along with the working example
     */
    public class GitHubService extends EventDispatcher
    {
        /**
         * constructor
         */
        public function GitHubService():void
        {    
            service = new HTTPService();
            service.addEventListener(HTTPConstants.COMPLETE, completeHandler);
        }

        /**
         * the service that performs the request to Github
         */
        private var service:HTTPService;

        /**
         * we dispatch an event once we have the source code from github
         */
        private function completeHandler(event:Event):void
        {
            dispatchEvent(new Event(&quot;dataReady&quot;));
        }

        private var _sourceCodeUrl:String = null;
        /**
         * The source code url we want to retrieve
         */
        public function get sourceCodeUrl():String
        {
            return _sourceCodeUrl;
        }
        public function set sourceCodeUrl(value:String):void
        {
            _sourceCodeUrl = value;
            service.url = sourceCodeUrl;
        }

        /**
         * json returns the retrieved GitHub JSON Object
         */
        public function get json():Object
        {
            return service.json;
        }

        /**
         * jsonToString returns the retrieved GitHub JSON Object as String
         */
        public function get jsonToString():String
        {
            return service.data;
        }

        /**
         * decode and return the base 64 content (real source code)
         */
        public function get sourceCode():String
        {
            return Base64.decode(service.json.content);
        }
        
        /**
         * trigger the HTTPService to retrieve the GitHub data
         */
        public function getContent():void
        {
            service.send();
        }
    }
}
</code></pre><p>We instantiate the HTTPService in the constructor, and declare an event listener for the <strong>HTTPConstants.COMPLETE</strong> event, so we perform actions when the data finishes loading. The action we do from this class is throw a new event &quot;<strong>dataReady</strong>&quot; to consume in our application.</p><p><strong>sourceCodeUrl</strong> will pass the GitHub url to be called by our service class, and fills <strong>HTTPService.url</strong> so HTTPService knows what url to target.</p><p>As we get the data loaded, we can manage it with <strong>HTTPService.data</strong>, and we have a convenient <strong>HTTPService.json</strong> getter to access the JSON Object that HTTPService already parses for us. We exposed this data in our json class as <strong>jsonToString</strong> and <strong>json</strong> getters respectively.</p><p>Finally, the source code is in the <strong>json.content</strong> variable, but comes encoded in <strong>base64</strong>, so we can use Apache Royale's <strong>decode</strong> function in the <strong>Base64</strong> class to get the decoded xml string to use in our example App. We exposed this in a convenient getter function in our service called <strong>sourceCode</strong>.</p><h2>Where to go from here</h2><ul><li><a href="https://apache.github.io/royale-docs/features/loading-external-data">Apache Royale documentation page about loading external data</a></li><li><a href="https://apache.github.io/royale-docs/component-sets/jewel/label">Jewel Label Royale Docs page</a></li><li><a href="https://apache.github.io/royale-docs/component-sets/jewel/button">Jewel Button Royale Docs page</a></li><li><a href="https://apache.github.io/royale-docs/component-sets/jewel/card">Jewel Card Royale Docs page</a></li></ul><p>The result of this code snippet is the following:</p><iframe width="100%" height="650" src="/blog-examples/BE0011_Loading_external_data_through_HTTPService/index.html"></iframe><p>(We're using an iframe to host the actual results of this example compilation. To see the example in a separate window click <a href="/blog-examples/BE0011_Loading_external_data_through_HTTPService/index.html" target="_blank">this link</a>.)</p><p>Full project with source code can be found <a href="https://github.com/apache/royale-asjs/tree/develop/examples/blog/BE0011_Loading_external_data_through_HTTPService">here</a>:</p><p><a class="btn btn-download" href="https://github.com/apache/royale-asjs/tree/develop/examples/blog/BE0011_Loading_external_data_through_HTTPService"><i class="fa fa-download"></i> Project Source Code</a></p></article></div></div><footer class="footer"><div class="footer-row"><div class="footer-column"><ul class="footer-list"><li class="apacheroyale"><a href="/">Apache Royale</a></li><li><a href="/">Home</a></li><li><a href="/features">Features</a></li><li><a href="/download">Download</a></li><li><a href="/ides">IDEs and Editors</a></li><li><a href="/showcase">Showcase</a></li><li><a href="/blog">Blog</a></li><li><a href="/team">Team</a></li><li><a href="/thanks-to">Thanks To</a></li><li><a href="https://apache.org/logos/#royale"><i class="fa fa-external-link-square"></i> Logos</a></li><li><a href="https://www.apache.org/licenses/"><i class="fa fa-external-link-square"></i> Apache License v2.0</a></li></ul></div><div class="footer-column"><ul class="footer-list"><li class="documentation"><a href="/docs">Documentation</a></li><li><a href="https://apache.github.io/royale-docs/get-started">Get Started</a></li><li><a href="/docs">Docs</a></li><li><a href="/asdoc">API Reference</a></li><li><a href="https://github.com/apache/royale-asjs/wiki"><i class="fa fa-github"></i>Wiki</a></li><li><a href="https://stackoverflow.com/questions/tagged/apache-royale"><i class="fa fa-stack-overflow"></i> StackOverFlow Tag</a></li></ul><ul class="footer-list"><li class="community"><a href="/get-involved">Community</a></li><li><a href="/get-involved">Get Involved</a></li><li><a href="/mailing-lists">Mailing Lists</a></li><li><a href="/faq">FAQ</a></li></ul><ul class="footer-list"><li class="development"><a href="/source-code">Development</a></li><li><a href="https://github.com/apache/royale-asjs/wiki/Apache-Royale-Source-Code-Repositories"><i class="fa fa-github"></i> Github</a></li><li><a href="https://github.com/apache/royale-asjs/issues"><i class="fa fa-github"></i> Issues</a></li><li><a href="/source-code"><i class="fa fa-code"></i> Source Code</a></li></ul></div><div class="footer-column"><ul class="footer-list"><li class="social_t">Social</li><li><a href="https://twitter.com/apacheroyale"><i class="fa fa-twitter"></i> Twitter</a></li><li><a href="https://facebook.com/ApacheRoyaleSDK/"><i class="fa fa-facebook"></i> Facebook</a></li><li><a href="https://www.linkedin.com/groups/12118437"><i class="fa fa-linkedin"></i> LinkedIn</a></li><li><a href="/feed/index.xml"><i class="fa fa-rss"></i> RSS</a></li></ul><ul class="footer-list"><li class="apache"><a href="https://www.apache.org/">Apache</a></li><li><a href="https://www.apache.org/"><i class="fa fa-external-link-square"></i> Apache</a></li><li><a href="https://www.apache.org/foundation/contributing.html"><i class="fa fa-external-link-square"></i> Donations</a></li><li><a href="https://www.apache.org/events/current-event"><i class="fa fa-external-link-square"></i> Events</a></li><li><a href="https://www.apache.org/foundation/sponsorship.html"><i class="fa fa-external-link-square"></i> Sponsorship</a></li><li><a href="https://www.apache.org/foundation/thanks.html"><i class="fa fa-external-link-square"></i> Thanks</a></li><li><a href="https://www.apache.org/security/"><i class="fa fa-external-link-square"></i>Security</a></li></ul></div><div class="aboutusdiv"><p class="aboutus">About Us</p><p class="aboutus_p"><img class="aboutus-logo" src="/img/apache-royale-logo-footer-circle-grey.svg"><a href="/" class="aboutus_a">Apache Royale™</a> is a highly productive open source application technology for building expressive frontend applications that outputs to different formats and deploy consistently on all major browsers, desktops and devices.</p><p><img class="aboutus-apache-logo" src="/img/Apache_PoweredBy.svg"> <a href="/" class="aboutus_a">Apache Royale™</a>, <a href="https://www.apache.org" class="aboutus_a">Apache™</a> and the <a href="https://www.apache.org/foundation/press/kit/" class="aboutus_a">Apache feather logo™</a> are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. Read more about our privacy policy on our <a href="/privacy-policy">Privacy Policy page</a>.</p></div></div><div class="asf">Copyright &copy; 2017-2022 <a href="https://www.apache.org">The Apache Software Foundation</a>, Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a></div></footer></body></html>