6

Following the autosuggest example, I need to retain and use object instead of plain string from amp-selector.

This is JSON from API:

[{
    "name": "Singapore",
    "cityCode": "SIN",
    "countryName": "Singapore",
    "type": "city"
}, {
    "name": "Sinop",
    "cityCode": "NOP",
    "countryName": "Turkey",
    "type": "city"
}, {
    "name": "Sinop",
    "cityCode": "OPS",
    "countryName": "Brazil",
    "type": "city"
}]

Rendering using AMP:

    <amp-list
        class="autosuggest-box"
        layout="fixed-height"
        height="130"
        src="<url>"
        id="autosuggest-list"
        single-item 
        items="."
    >
        <template type="amp-mustache">
        <amp-selector
            id="autosuggest-selector"
            keyboard-select-mode="focus"
            layout="container"
            on="
            select:
                AMP.setState({
                    locationObj: event.targetOption,
                    showDropdown: false
                }),
                autosuggest-list.hide"
        >
            {{#.}}
            <div
                class="location-item no-outline"
                role="option"
                tabindex="0"
                on="tap:autosuggest-list.hide"
                option="{{.}}"
            >{{name}}, {{countryName}}</div>
            {{/.}}
        </amp-selector>
        </template>
    </amp-list>

Thanks to this answer for {{.}} syntax which is nowhere in Mustache docs. However, the binded field of locationObj in amp-bind prints [object Object] and when I try to use locationObj.name it prints null

Here's the bind code

    <input
    type="text"
    class="search-box"
    on="
        input-debounced:
        AMP.setState({
            showDropdown: event.value
        }),
        autosuggest-list.show;
        tap:
        AMP.setState({
            showDropdown: 'true'
        }),
        autosuggest-list.show"
    [value]="locationObj ? locationObj.name : ''"
    value=""
    required
    autocomplete="off"
    />

AMP Docs doesn't state any way to log anything in console so I have on idea what is being set in locationObj through {{.}}

adnanyousafch
  • 1,172
  • 7
  • 26
  • not sure that `#.` and `/.` will work in AMP. `{{.}}` will read the JSON array. You may have to identify a JSON key. If you put your JSON into a child structure, you may be able to use the parent key to call the array. – Jay Gray Oct 14 '17 at 12:34
  • @JayGray Yes, that would work if we change our structure to include an array in `items` key. But unfortunately, we cannot as API is being consumed in production for 4 different platforms. – adnanyousafch Oct 16 '17 at 02:42

1 Answers1

4

Thanks to Carlos at Amp Google Forum. The correct way to save and access the response of <amp-list> is through <amp-state>.

<amp-list class="autosuggest-box"
    layout="fixed-height"
    height="130"
    src="http://url.returning.json.array.com?query="
    [src]="'http://url.returning.json.array.com?query=' + query"
    id="autosuggest-list"
    single-item 
    items=".">
    <template type="amp-mustache">
    <amp-selector
        id="autosuggest-selector"
        keyboard-select-mode="focus"
        layout="container"
        on="
        select:
            AMP.setState({
                locationObj: allLocations.filter(x=>x.code == event.targetOption)[0],
                showDropdown: false
            }),
            autosuggest-list.hide"
    >
        {{#.}}
        <div
            class="location-item no-outline"
            role="option"
            tabindex="0"
            on="tap:autosuggest-list.hide"
            option="{{code}}"
        >{{name}}, {{countryName}}</div>
        {{/.}}
    </amp-selector>
    </template>
</amp-list>

<amp-state
  id="allLocations"
  src="http://url.returning.json.array.com?query="
  [src]="'http://url.returning.json.array.com?query=' + query"
  ></amp-state>

Defining same [src] in <amp-state> as in <amp-list> stores the response in state variable as well, which can later be used to take an item based on a unique member of the object (e.g. allLocations.filter(x=>x.code == event.targetOption)[0] in this case) from locally saved array in state.

adnanyousafch
  • 1,172
  • 7
  • 26