Author: Yoko Ishioka

  • Contentful Error: When searching on references you must specify the Content Type of the reference

    Contentful Error: When searching on references you must specify the Content Type of the reference

    If you’re using the incredibly lean, headless content management system, or CMS, Contentful, you may have seen this error:

    “When searching on references you must specify the Content Type of the reference. Please send a Content Type id as a query parameter.”

    Background

    I wanted to use a different model type for category than I used for tags, short-text list, because the reference type allows you to control and manage category names outside of the blog post model. If you want to query entries that have the type short-text list, you can write a function like this:

      getBlogPostsByTag(tag:string):Promise<BlogPost[]> {
        return this.blogService.getEntries({
          content_type: this.contentTypeIdBlogPost,
          'fields.tags': tag,
          'order': '-fields.publishDate'
        })
        .then(res => res)
        .catch(error => error);
      }
    

    Solution

    If you want to query entries that have a reference data type, you have to specify the content type of the reference data. You can resolve the above error by writing a function like this:

      getBlogPostsByCategory(category:string):Promise<BlogPost[]> {
        return this.blogService.getEntries({
          content_type: this.contentTypeIdBlogPost,
          'fields.category.sys.contentType.sys.id':        
          this.contentTypeIdBlogCategory,
          'fields.category.fields.name': category,
          'order': '-fields.publishDate'
        })
        .then(res => res)
        .catch(error => error);
      }
    

    Note: Contentful allows you to query reference types only if they contain one field. For example, my category only has the name field.

    Also, to future-proof any changes to the content type IDs by identifying them only in one place (technically two, one for dev and one for prod), I am storing those values in my app’s environment files. So make sure you substitute those variables with your content type IDs.

  • How to create a self-updating navigation menu in Angular

    How to create a self-updating navigation menu in Angular

    Rather than hardcoding hyperlinks or buttons to create your website/web app’s navigation menu, you can leverage Angular Routes to pass data to a Menu Component that decides whether or not to render that data based on conditionals! What does that mean?

    You never have to manually code navigation menus in HTML again. Instead, you can create an Angular (or plain Javascript) component, aka template, that is smart enough to create the actual code that the browser needs to render your menu.

    Example

    Ultimately, as a cloud engineer, your goal should be to create settings so others can modify your code without touching or modifying the actual code. (That is what user interface/content management system developers, like myself, have been obsessing over the past decade.)

    That’s why I chose to pass the following variables to create the menu:

    1. show: boolean – sets whether or not the navigation link gets displayed in the menu
    2. showChildren: boolean – determines whether or not to match the exact parameter of the router link when navigating the route
    3. navLabel: string – sets what the label should be for the navigation menu button
    4. navIcon: string – decides which SVG should be included for the navigation menu button
    5. title: string – sets the title attribute of the page as well as the title meta tags
    6. description: string – sets the description meta tags appropriate to the page

    Here is an example of one of my routes in JSON format:

    app-routing.module

    export const routes: Routes = [{
      path: '',
      component: PageIndexComponent,
      data: {
        show: true,
        showChildren: false,
        navLabel: 'Home',
        title: 'Cloud Engineering Studio',
        description: 'Adaptive smart learning: cloud engineering based on human behavior',
        icon: 'house'
      }
    }];
    

    Here is the HTML template I used to display the above data:

    menu.component

    <nav>
      <ng-container *ngFor="let route of currentRoutes">
         <ces-button *ngIf='route.data.show && !route.data.showChildren' ngClass='nav-button' size='small' [routerLink]="[route.path]"
    [title]="route.data.title" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
    true}" >
         <ces-svgs [type]="route.data.icon" class="icon"></ces-svgs><br>{{ route.data.navLabel }} 
         </ces-button>
    
         <ces-button *ngIf='route.data.show && route.data.showChildren' ngClass='nav-button' size='small' [routerLink]="[route.path]" [title]="route.data.title" routerLinkActive="active">
         <ces-svgs [type]="route.data.icon" class="icon"></ces-svgs><br>
         {{ route.data.navLabel }} 
         </ces-button>
    
       </ng-container>
     </nav>
    
  • Welcome to the Cloud Engineering Studio

    Welcome to the Cloud Engineering Studio

    Thanks for visiting the Cloud Engineering Studio!

    As a front-end developer and engineer since 2010, I’ve learned that the web is a continually evolving beast. That is why I created this website, to house everything related to the front end and the cloud.