[full stack development] proficient in mean: when mean encounters meetup.com and microdata

Time:2021-11-23

First, add upcoming event information from meetup.com to the ugli home page.

HTML and microdata

If you visit the on meetup.comHTML5 DenverUsers Group, you will see a web page similar to figure 1.

Figure 1. Meetup.com information of an upcoming HTML5 Denver user group meeting

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

It can be seen that all the raw materials needed to further customize the ugli home page using the information of upcoming events are on the meetup.com page (the title of the upcoming speech, meeting time and place, etc.), but the design of the meetup.com page is closely coupled with this data. The information you want to extract and reuse in the mean application is cluttered with HTML elements, as shown in Listing 1. (I edited the HTML for clarity and brevity.)

Listing 1. Meetup. Com HTML source code

<ul>
    <li itemscope="" itemtype="http://data-vocabulary.org/Event">

        <span itemprop="eventType" 
              style="display:none;">Meetup</span>
        <h3>
            <a href="http://www.meetup.com/HTML5-Denver-Users-Group/events/160326502/" itemprop="url">
                <span itemprop="summary">"Developing Offline Applications" and "HTML 5 Animations"</span>
            </a>
        </h3>

        <!-- snip -->
    </li>
</ul>

Title of the activity(Developing offline applications and HTML 5 animations)Drill down into multiple layers nested in HTML. In the case of HTML documents (and your web browser), this arbitrary string is simply nested in an unordered list(<ul>)Several list items in(<li>)One. This list item has a three-level title(<h3>)Generally, both the secondary and primary headings are defined in the document hierarchy. Inside the title is a hyperlink(<ahref>), which in turn contains an arbitrary text<span>

All these HTML tags are essential for the information to be displayed in the format that meetup.com wants. Your task is to display information in your application in a completely different way: you need to find a way to separate information from the display.

You need to use two different semantic layers, as shown in Listing 1. The most basic semantic layer I have just discussed: one is a list item, and the other is a hyperlink. This is it.fileSemantics. The other layer iseventSemantics, byeventTypeurlandsummaryAnd other keywords. These keywords have nothing to do with how the document is rendered. They hint to search engines (and beginners viewing HTML source code) the “higher meaning” of information. These properties areHTML MicrodataPart of the specification. (for more information about microdata and its metadata predecessors, seeMicroformats, microdata and rdfa! Oh, my God!Sidebar.)

This particular list item contains only oneeventInformation about. Search engines know this fact because the person who designed the page added to the list itemitemtype="http://data-vocabulary.org/Event"。 The page contains many arbitrary hyperlinks with
itemprop="url"Your hyperlink iseventOwn link.eventTypebyMeetup– an arbitrary string, but meetup.com uses it consistently on all its web pages. ActivesummaryBy banditemprop="summary"Attribute
<span>To identify.

<span>Element is one of some HTML elements that browsers ignore when rendering a page.<b>The text within the element is rendered in bold font;<h1>Text display font size ratio<h2>Larger text;<a>Text is clickable, usually blue and underlined. Of course, all of these default style rules can be overridden using CSS. but<span>Tags exist only to add your own CSS Styles – or forListing 1HTML snippet of meetup.com in"Developing Offline Applications" and "HTML5 Animations"String wrapped initemprop="summary"Semantic tags.

For a complete list of metadata items that can be added to the mean tag to further describe the event, first visit meetup.com’s URL for defining the event:http://data-vocabulary.org/Event

Add a placeholder event to the home page

With a general understanding of how meetup.com displays event information, you can do the same for the ugli application.

In the root of the test application, typemongodTo start mongodb, and then typegruntStart the web application. Access in a web browserhttp://localhost:3000You should see the home page you customized in the previous issue (as shown in Figure 2).

Figure 2. Ugli home page

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

I want to add an upcoming HTML5 Denver user group event to the home page. The rest of this tutorial will do this iteratively. First, add some static placeholder data to a wireframe that depicts the basic appearance of the page.

Open public / modules / core / views / home.client.view.html in a text editor. Under the banner, add a new tag for the activity, as shown in Listing 2.

Listing 2. Public / modules / core / views / home. Client. View. HTML

<section data-ng-controller="HomeController">
  <div class="jumbotron text-center">
    <!-- snip -->
  </div>

  <div class="row">
    <div>Monday, September 22, 2014</div>
    <h3><a href="http://www.meetup.com/HTML5-Denver-Users-Group/events/160326502/">
    "Developing Offline Applications" and "HTML 5 Animations"</a></h3>
    <div class="col-md-4">
     <h4>When</h4>
     <p>6pm</p>
     <h4>Where</h4>
     <address>
       <span>Rally Software</span><br>
       1550 Wynkoop<br>     
       Denver, CO<br>
     </address>
    </div>

    <div class="col-md-8">
     <p><b>6 pm : "Developing Offline Applications with HTML 5" by Venkat Subramaniam</b></p> 
     <p><b>7 pm: Dinner and Networking</b></p> 
     <p><b>7:30 pm: "HTML 5 Animations - building true richness on the web" by Venkat Subramaniam</b></p>
    </div>
  </div>
</section>

When viewing the updated home page in the browser, it should look like Figure 3.

Figure 3. Ugli home wireframe

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

With basic HTML

The default style is more beautiful. To do this, you need to add some semantics.

Bootstrap provides the default structured HTML elements you use (such as<div>and<h3>)Built in styles for. It also provides additional structured classes that do not belong to the default HTML elements, such asrow
andcol

Novice web developers often consider the structure of web pages rather than the information displayed. As a result, they use things likebig-red-italicandleft-column-headerWrite a custom CSS class with such a name. Grammatically speaking, there is nothing wrong with this method, but I find that it is likeevent-dateandevent-locationWith such semantic names, the long-term maintenance of the website is easier. In this way, when the customer returns a year later and asks to mark all subtotals in green instead of red, I can write a CSS class to identify the displayed subtotalsWhat
(subtotals), notHow to display(green-body-text)。 I’m also unlikely to inadvertently change other on the page, which happens to be used as wellgreen-body-textElements of CSS rules.

Return to the HTML you just wrote and add some CSS classes with appropriate semantics, such aseventevent-dateand
event-title

<div class="row center-block event">
<div class="event-date">Monday, September 22, 2014</div>
<h3 class="event-title"><a href="http://www.meetup.com/HTML5-Denver-Users-Group/events/160326502/">
    "Developing Offline Applications" and "HTML 5 Animations"</a></h3>

center-blockStructure class fromLast issueBootstrap library described in. You will see later thateventClasswidthReduced to 75%
When,center-blockIt will ensure that the blank areas on the left and right are equal.

This is ideal for mixing structural and semantic classes on the same element. In fact, in the long run, it makes it easier for me to quickly identify which classes are application specific(event-*), which classes are generic(rowcenter-block)。

After adding these classes to HTML, you can define some custom CSS rules. Open public / modules / core / CSS / core.css in a text editor. Because each module has its own CSS, the concept of “component oriented” can be maintained. Moreover, by crawling the whole subdirectory tree, it is easier to share modules among projects.

Add CSS style rules, as shown in Listing 3.

Listing 3. Public / modules / core / CSS / core. CSS

.event {
    width: 75%;
}

.event-date {
    font-style: italic;
}

.event-title {
    margin-top: 0;
}

Now your home page looks less rough and more beautiful, as shown in Figure 4.

Figure 4. Ugli home page with CSS Style

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

Finally, return to add microdata metadata again. Can I skip this step and use microdata elements in CSS rules without defining custom elements? Certainly. But I want to separate them. After all, they serve two different purposes. One is for CSS style and the other is for search engine optimization (SEO). Suppose you encountered a user case 5 years ago that requires you to migrate microdata to another updated specification. It would be a pity if the side effects that affect the appearance of the website while meeting the requirements of the case. These two characteristics should be completely different.

Open public / modules / core / views / home.client.view.html in the text editor again. Add a new semantic microdata tag to the activity, as shown in Listing 4. (for an example of using microdata to tag an activity, seeRich snippet – activity。)

Listing 4. Adding microdata

<div class="row center-block event" 
   itemscope 
   itemtype="http://data-vocabulary.org/Event">
  <span itemprop="eventType" 
      style="display:none;">Meetup</span> 
  <time class="event-date" 
      itemprop="startDate" 
      datetime="2014-09-22T18:00-06:00">Monday, September 22, 2014</time>
  <h3 class="event-title"><a href="http://www.meetup.com/HTML5-Denver-Users-Group/events/160326502/" 
    itemprop="url"><span itemprop="summary">"Developing Offline Applications" and 
    "HTML 5 Animations"</span></a></h3>
  <div class="col-md-4">
    <h4>When</h4>
    <p>6pm</p>
    <h4>Where</h4>
    <address itemprop="location" 
         itemscope 
         itemtype="http://data-vocabulary.org/?Organization">
      <span itemprop="name">Rally Software</span><br>
      <span itemprop="address" 
          itemscope 
          itemtype="http://data-vocabulary.org/Address">
        <span itemprop="street-address">1550 Wynkoop</span><br>  
        <span itemprop="locality">Denver</span>, <span itemprop="region">CO</span><br>
      </span>
    </address>
  </div>

  <div class="col-md-8" itemprop="description">
    <p><b>6 pm : "Developing Offline Applications with HTML 5" by Venkat Subramaniam</b></p> 
    <p><b>7 pm: Dinner and Networking</b></p> 
    <p><b>7:30 pm: "HTML 5 Animations - building true richness on the web" by Venkat Subramaniam</b></p>
  </div>
</div>

It must take a lot of work to get exactly the same display results in the browser, isn’t it? But happily, because of all the semantic data you have painstakingly added, your website has risen to the top of the search results.

We won’t explain listing 4 in detail line by line, but I’ll just point out some important points.

AndListing 1Like the meetup. Com example in, we added aeventType(because it is only used for SEO):

<span itemprop="eventType" 
      style="display:none;">Meetup</span>

Next, add a date to the activity for use by people and machines:

<time class="event-date" 
      itemprop="startDate" 
      datetime="2014-09-22T18:00-06:00">Monday, September 22, 2014</time>

As a human, you can analyze strings immediatelyMonday, September 22, 2014, recognize that it is a date. You can also identify 9 / 22 / 2014 and 2014-09-22 as the same date. But computers pay more attention to literal content, and small format changes like this can lead to major failures. In this example, you made several changes to disambiguate:

  • You convert HTML elements from generic<div>Upgrade to more specific<time>(a new HTML5 element).
  • CSS event-dateClass identifies the content of the data, not its appearance*itemprop="startDate"The microdata attribute identifies this date aseventofstartDate。* datetimeProperties (HTML5)<time>Element) clearly indicates that the time is in ISO 8601 format. In this way, it can not only provide a time that the machine can use, but also provide a well formatted time for display and human use.

The biggest changes to HTML include the address of the activity, as shown in Listing 5. You areEventA variety of new modes are embedded in the mode –Organization and Address

Listing 5. Adding microdata for organizations and addresses

<h4>Where</h4>
<address itemprop="location" 
         itemscope 
         itemtype="http://data-vocabulary.org/?Organization">
    <span itemprop="name">Rally Software</span><br>
    <span itemprop="address" 
          itemscope 
          itemtype="http://data-vocabulary.org/Address">
        <span itemprop="street-address">1550 Wynkoop</span><br>  
        <span itemprop="locality">Denver</span>, <span itemprop="region">CO</span><br>
    </span>
</address>

Make your browser aware of microdata

Now that you have added some micro data to the website, how can you make sure you have added it correctly? The easiest way is to use a microdata extension for browsers. Among a variety of unofficial micro data extensions, what I like to use in Chrome isSemantic inspector

After installation, this browser extension usually remains hidden until you visit a web site that uses microdata. When the semantic inspector finds microdata in the current web page, it will display a red m icon in the address bar. You may be surprised at how often this small icon pops up; You will see it on many popular and mainstream websites, including Google, time.com and walmart.com. Click the icon to display details, as shown in Figure 5
As shown in:

Figure 5. Viewing microdata using semantic inspector

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

Now that you have a basic HTML wireframe annotated with microdata properties, it’s time to fill in new JSON from these wires. To do this, create a new event module that contains controllers, views, models, and services.

Create an angularjs module

stayLast issueIn, you use yeoman to build a complete crud module, including express routing and a mongoose model. For this user case, no server-side infrastructure is required because the raw JSON data comes from an external web application. Fortunately, the creator of the meanjs yeoman generator foresaw this need and provided another generator only for the client-side angularjs part of the application.

typingyo meanjs:angular-module eventsTo create a file namedeventsNew angularjs module. AngularJSmodularIs a logical grouping of files specific to a particular data type in your application. According to the description of the official angularjs document, “modules can be regarded as containers for different parts of your application (controllers, services, filters, instructions, etc.)

When prompted, select all the elements in the list, as shown in Listing 6.

Listing 6. Generating a module

[?] Which folders would you like your module to include? 
 ? config
 ? controllers
 ? css
 ? directives
 ? filters
 ? img
 ? services
 ? tests
 ? views

 create public/modules/events/events.client.module.js

According to the description just now, your module is just an empty directory collection. You won’t be writing every angularjs
Each directory is used in the module, but it’s also good to know that there is an easy to remember and understand place to put all parts of the module when the time is ripe.

The next step is to add a controller to the module.

Create an angularjs controller

After building a module, it is also very easy to build a controller. typingyo meanjs:angular-controller eventsAnd select
eventsModule, as shown in Listing 7.

Listing 7. Generating a controller

[?] Which module does this controller belongs to? 
  articles 
  core 
? events 
  talks 
  users 

create public/modules/events/controllers/events.client.controller.js
create public/modules/events/tests/events.client.controller.test.js

You can see that the yeoman generator places the controller in the controllers directory and the associated tests in the tests directory of the module you specify.

A reasonable question to ask at the moment is “why did I create a controller and why should I pay attention to it?” recall that angularjs is a clientModel view controller (MVC)Frame. You will end up with a view (the HTML you created earlier in this tutorial)<div>Element), filled with model data (a JSON structure filled with activity data from meetup. Com). How does the view access the model? The work of the controller is to collect all parts and provide the model data it needs for the view.

The following simple example demonstrates how the parts of MVC fit together. open in text editor
Public / modules / events / Controllers / events. Client. Controller. JS, as shown in Listing 8.

Listing 8. An empty, stub free angularjs controller

'use strict';

angular.module('events').controller('EventsController', ['$scope',
  function($scope) {
    // Events controller logic
    // ...
  }
]);

Later, we will bind this controller to a specific DOM element.$scopeVariables will be responsible for the important work of passing the model to the view.

towards$scopeAdd atitleVariables (models), as shown in listing 9.

Listing 9. Placing a$scopeAdd variable to angularjs controller

'use strict';

angular.module('events').controller('EventsController', ['$scope',
  function($scope) {
    $scope.title = 'High Performance WebSocket';

  }
]);

Next, you willEventsControllerAdded to public / modules / core / views / home.client.view.html
EventIn the DOM element (view):

<div class="row center-block event" 
       itemscope 
       itemtype="http://data-vocabulary.org/Event"
       ng-controller="EventsController">

As you might have guessed, this code binds the controller to a DOM element.$scopeVariable only for this<div>And its child elements are valid. If you like, you can bind a controller to many different DOM elements. Each element gets a unique instance of the new controller and its own unique$scope

Next, add one to your wireframe HTML{{title}}Placeholder to replace hard coded text:

<h3 class="event-title"><a href="http://www.meetup.com/HTML5-Denver-Users-Group/events/160326502/" 
itemprop="url"><span itemprop="summary">{{title}}</span></a></h3>

When viewing the results in a web browser, you should see{{title}}Placeholder replaced byEventsControllerThe text provided is shown in Figure 6.

Figure 6. Placeholder replaced with actual text

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

Now that you have a simple and effective example, it’s time to analyze it in detail. (in other words, your application is working properly, and it’s time to destroy it again.) if you like, you can ask$scopeAdd many variables, which can be simple single values or complete JSON objects.

Soon, you’ll see how to issue an HTTP request to meetup.com to retrieve the JSON for the next upcoming event. By then, in$scopeAdd some simplified simulation data to simulate the data you will get from the actual Ajax call, as shown in listing 10.

Listing 10. Simulated JSON response

'use strict';

angular.module('events').controller('EventsController', ['$scope',
  function($scope) {
        $scope.title = 'High Performance WebSocket';
        $scope.event = {
          'name': '"Developing Offline Applications" and "HTML 5 Animations"',
          'time': 1411430400000,
          'event_url': 'http://www.meetup.com/HTML5-Denver-Users-Group/events/160326502/',
          'description': '<p><b>6 pm : "Developing Offline 
          Applications with HTML 5" by Venkat Subramaniam</b></p>',
          'venue': {
            'name': 'Rally Software',
            'address_1': '1550 Wynkoop',
            'city': 'Denver',
            'state': 'CO',
          }      
       }
    }
]);

As you can see,$scope.eventVariable contains a complex, nested JSON object. Edit your view to take advantage of the new model data, as shown in listing 11.

Listing 11. Adding more placeholders to HTML

<h3 class="event-title"><a href="{{event.event_url}}" itemprop="url"><span 
itemprop="summary">{{event.name}}</span></a></h3>
<div class="col-md-4">
  <h4>When</h4>
  <p>{{event.time}}</p>
  <h4>Where</h4>
  <address itemprop="location" 
           itemscope 
           itemtype="http://data-vocabulary.org/Organization">
    <span itemprop="name">{{event.venue.name}}</span><br>
    <span itemprop="address" 
          itemscope 
          itemtype="http://data-vocabulary.org/Address">
      <span itemprop="street-address">{{event.venue.address_1}}</span><br>   
      <span itemprop="locality">{{event.venue.city}}</span>, 
      <span itemprop="region">{{event.venue.state}}</span><br>
    </span>
  </address>
</div>

<div class="col-md-8" itemprop="description">
  {{event.description}}
</div>

When viewing the results in a web browser, you should display the results from as long as you add placeholders to the template view$scope.eventAs shown in Figure 7.

Figure 7. Ugli home page with simulated JSON data

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

Before creating an angularjs service to obtain actual and real-time data, you must complete two simple tasks related to the view: add some angularjs filters to format the date and{{event.description}}The rendered html is displayed in the placeholder instead of the original, escaped HTML code

Add angularjs filter

AngularJS filter(with camera or instagram)
Filters (much like) can change the appearance of data. Add filters to the view because they affect the appearance of the model data without changing the content itself.

By adding a vertical bar after the data element(|)And a filter name, such as{{product_code | uppercase}}
As shown in, you can apply a filter to the template placeholder. Angularjs provides many built-in filters, including
uppercaselowercasecurrencyand
number。 You can even write your own custom filters.

One of the filters I’ve been using isdateFilter that enables you to format the appearance of date values using a custom mode.

For example, to a previously createdtimeElement applies adatefilter:

<time class="event-date" 
  itemprop="startDate" 
  datetime="{{event.time | date:'yyyy-MM-ddTHH:mm:ss:Z'}}">{{event.time | 
  date:'EEEE, MMMM, d, yyyy'}}</time>

Notice that you used the same filter for two different filtersevent.timeField.EEEEThe code shows the full English of the day of the week, such as Monday.EEEThe code abbreviates the day of the week as mon;EEAbbreviated as Mo;EAbbreviated as
M。MThe code also applies to month names.dThe code applies to a day in January,yThe code applies to years.

event.timeThe field appears multiple times on the home page. changeWhenTo display the hour and am / PM suffix:

<h4>When</h4>
<p>{{event.time | date:'h a'}}</p>

The extensive use of angularjs filter in mean application highlights an important principle of MVC design pattern: model data should be independent of any view content.

With the rightevent.timeAfter formatting, onlyevent.descriptionThe appearance needs to be repaired. To do this, you must let angularjs know that it can safely display the non escaped HTML of this field.

Show UN escaped HTML

All JSON data used so far is pure data, that is, there are no nested HTML elements.event.descriptionField is an exception.

Whenever you receive HTML from an external source, whether trusted or not, you face a potential security risk. Included HTML can lead to unwanted JavaScript libraries that may expose your data to other websites.

To guard against this risk, angularjs will automatically clean up the templated data, escape any HTML elements it encounters, and replace the “real” angle brackets with the equivalent representation of the escape&gt;and&lt;。 This behavior is not explicit filtering as seen in the previous section, but a similar concept.

aboutevent.descriptionField, you must tell angularjs that there is no problem displaying external HTML and local HTML together. To do this, adjust your template and delete it{{event.description}}Placeholder and replace it withng-bind-htmlProperties:

<div class="col-md-8" itemprop="description" ng-bind-html="event.description"></div>

Visible and escaped when viewing the home page in the browser<b>and<p>HTML elements should disappear and be replaced by rendered text.

With the controller, model, and view, the last step is to replace the mock JSON content in the controller with the real-time data returned from the Ajax request. To perform this step, you need to add another element to the module: aservice

Create a service

An angularjs is usedserviceTo make Ajax requests, which is the perfect solution for interacting with external meetup.com APIs.

You may want to make Ajax requests directly from the controller, but it’s a little short-sighted. What if this activity data is required in other controllers? You certainly don’t want to copy and paste source code between controllers, do you? To facilitate sharing the same data across multiple controllers, create a service.

typingyo meanjs:angular-service eventsTo create aeventsService, as shown in listing 12. Select at the prompteventsmodular.

Listing 12. Generating an angularjs service

$ yo meanjs:angular-service events
[?] Which module does this service belongs to? 
  articles 
  core 
events 

  talks 
  users 

create public/modules/events/services/events.client.service.js

Angularjs provides a$httpA pre built service to issue http / Ajax requests. (all angularjs services have one)$Prefix.) To use$http, you need to inject it into your service. stayeventsAfter the service runs normally, inject it intoEventsControllerYes. (angularjs uses dependency injection everywhere.)

Remember when you wereEventsControllerUsed in$scopeObject?$scopeIs a service injected into the controller. As shown in listing 13, inject$scopeThe way to a service is to declare it and then pass it to a function as a parameter.

Listing 13. Injection$scopeservice

'use strict';

angular.module('events').controller('EventsController', ['$scope',
  function($scope) {
    $scope.title = 'High Performance WebSocket';

  }
]);

Typing the service name twice seems redundant, but it facilitates the streamlining and concatenation process that occurs when preparing to deploy the mean application to the production environment.

You’ve seen how to inject a service, and it’s time to apply this knowledge. Open public / modules / events / services / events. Client. Service. JS, as shown in listing 14
As shown in.

Listing 14. Public / modules / events / services / events. Client. Service. JS

'use strict';

angular.module('events').factory('Events', [
    function() {
        // Events service logic

        // ...

        // Public API
        return {
            someMethod: function() {
                return true;
            }
        };
    }
]);

injection$httpService, as shown in listing 15.

Listing 15. Injection$httpservice

angular.module('events').factory('Events', ['$http',
        function($http) {
            // Events service logic
            // ...

            // Public API
            return {
                someMethod: function() {
                    return true;
                }
            };
        }
    ]);

Next, you willsomeMethodChange togetNextEventAnd remove the stubs of some basic functions, as shown in listing 16.

Listing 16. Returning JSON from an Ajax call

'use strict';

angular.module('events').factory('Events', ['$http',
  function($http) {
    // Public API
    return {
      getNextEvent: function() {
        var url = 'http://api.meetup.com/2/events?status=upcoming&order=
        time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&desc=
        false&offset=0&photo-host=public&format=json&page=1&fields=
        &sig_id=13848777&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&callback=JSON_CALLBACK';

        var request = $http.jsonp(url);
        return request;
      }
    };
  }
]);

The (detailed) URL will return the next upcoming event of HTML5 Denver user group. (meetup.com provides a good examplesandboxTo use its API.) If the URL is
Copy it to your browser and you will get the full JSON response. For clarity, I edited the response, as shown in listing 17.

Listing 17. JSON response from meetup. Com API

{
  "results": [
    {
      "status": "upcoming",
      "visibility": "public",
      "venue": {
        "id": 21506832,
        "name": "Rally Software",
        "state": "CO",
        "address_1": "1550 Wynkoop",
        "city": "Denver"
      },
      "id": "160326502",
      "time": 1411430400000,
      "event_url": "http:\/\/www.meetup.com\/HTML5-Denver-Users-Group\/events\/160326502\/",
      "description": "<p><b>6 pm : \"Developing Offline Applications with HTML 5\" 
      by Venkat Subramaniam<\/b><\/p> ",
      "name": "\"Developing Offline Applications\" and \"HTML 5 Animations\""
    }
  ],
  "meta": {
    "count": 1,
    "total_count": 3,
    "next": "http:\/\/api.meetup.com\/2\/events?status=upcoming&sig_id=13848777&
    order=time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&
    desc=false&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&photo-host=public&offset=1&
    format=json&page=1&fields="
  }
}

The JSON objects in the resulting array should look familiar. You deletedEventsControllerSimilar data in. Note, however, that the full JSON response contains other information that is not necessary to render the data on the home page (such asmeta)。 Fortunately, the JSON response can be transformed before it is passed. Add transformation logic to
eventsService, as shown in listing 18.

Listing 18. Transforming JSON responses

    // Public API
    return {
      getNextEvent: function() {
        var url = 'http://api.meetup.com/2/events?status=upcoming&order=
        time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&desc=
        false&offset=0&photo-host=public&format=json&page=1&fields=
        &sig_id=13848777&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&callback=JSON_CALLBACK';

        var returnFirstElement = function (data, headers) {
                    return data.results[0];
                };

        var request = $http.jsonp(url, {transformResponse: returnFirstElement});
        return request;
      }
    };
  }

]);

With the transformation logic, JSON will contain only the first element from the result array. All other additional JSON information is discarded.

To help in the development process, you can addsuccessanderrorThe handler function, as shown in listing 19. This code logs the response data to the console. You are free to define this code or ignore it altogether.

Listing 19. AddingsuccessanderrorProcessing function

    // Public API
    return {
      getNextEvent: function() {
        var url = 'http://api.meetup.com/2/events?status=upcoming&order=
        time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&desc=
        false&offset=0&photo-host=public&format=json&page=1&fields=
        &sig_id=13848777&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&callback=JSON_CALLBACK';


        var returnFirstElement = function (data, headers) {
                    return data.results[0];
                };

        var request = $http.jsonp(url, {transformResponse: returnFirstElement});

        request.success(function(data, status, headers, config) {
            console.log('SUCCESS');
            console.log(data);
        });
        request.error(function(data, status, headers, config) {
            console.log('ERROR');
            console.log(data);
        });

        return request;
      }
    };
  }
]);

Now?eventsThe service is complete and can be injected intoEventsControllerYes. modifyEventsController, as shown in listing 20.

Listing 20. AddingeventsService injection intoEventsControllerin

'use strict';

angular.module('events').controller('EventsController', ['$scope', 'Events',
  function($scope, Events) {
        $scope.event = undefined;

        Events.getNextEvent().success(function(data){
          $scope.event = data;          
        });
    }
]);

If all functions work as expected, you should see a complete description of the activity on the home page, as shown in Figure 8. If you see more details in the speech description than in the previous simulation, you will know that everything is normal.

Figure 8. Practical application of a complete and effective example

[full stack development] proficient in mean: when mean encounters meetup.com and microdata

Hide flashing styleless content

In the interval between the first presentation of the home page and its Ajax request to meetup.com, you may have noticed annoyingFOUC(flash of Unstyled content, no style content flashes). If not, refresh the browser twice and you should see it.

Foucs are not particularly significant errors, but they certainly make your application look unprofessional. Fortunately, angularjs developers provide a concise solution to this common problem.

useng-showMake the last change to home.client.view.html to hide the view until the model data is in place:

<div class="row center-block event" 
     itemscope 
     itemtype="http://data-vocabulary.org/Event"
     ng-controller="EventsController"     ng-show="event">

takeng-showAdd attribute to<div>In, it will lead to the whole<div>Hide until filled$scope.eventVariable. When the Ajax request for meetup.com returns JSON (model), the
<div>(view).

Conclusion

Ugli applications are really beginning to take shape. You pull in JSON data from an external API and format the resulting view with microdata so that search engines and other automated processes can access the same information as people viewing web pages.

download

Sample codewa-mean4.zip

Full stack development, proficient in the first three articles of mean series:

[full stack development] proficient in mean: mean stack
[full stack development] proficient in mean: understand a mean application
[full stack development] proficient in mean: use mean and ugli crud to realize responsive web design

Original source:Proficient in mean: when mean meets meetup.com and microdata

Recommended Today

Application of observer pattern in design pattern in Ruby Programming

Observer mode(sometimes referred to as publish / subscribe mode) is softwareDesign patternA kind of.In this mode, a target object manages all its dependent observer objects and actively notifies when its own state changes.This is usually achieved by calling the methods provided by each observer. When implementing the observer mode, it should be noted that the […]