60 min
Saito
  1. 1. Information
    1. 1.1. Ingredients
    2. 1.2. Functions
  2. 2. Create the application
    1. 2.1. Frontend
    2. 2.2. Backend
  3. 3. Customize the application
    1. 3.1. Frontend
    2. 3.2. Backend
  4. 4. Deploy the application
    1. 4.1. Backend
    2. 4.2. Frontend
  5. 5. Download
  6. 6. Version

There are many services that share photos. It is good to know how to implement an image search function in your SPA.

In this tutorial, I explain how to search images by using Google and Flickr API.

Information

Ingredients

  • Template: Form Search
  • API Loigcs: Flickr Get Popular Images, Google Custom Search

Functions

  • Searching for images on Flickr or Google.
  • Displaying a list of images matching a keyword.

Create the application

Frontend

  1. Choose the Form Search Template.

  2. Customize the UI in K5 Playground.

Backend

  1. Add a WebAPI named image/flickr and activate GET.

  2. Edit the API Logic of GET image/flickr endpoint.

    1. Select the GET image/flickr endpoint.

    2. Add the Flickr Get Search images API Logic from SNS menu at the right pane.

    3. Edit the code for query options and credentials.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      var options = {
      text: req.query.keyword || 'image',
      per_page: req.query.limit || 100,
      page: req.query.offset || 0,
      };

      var flickrOptions = {
      api_key: '[API key]', // API key that you get from Flickr
      secret: '[secret]', // API key secret that you get from Flickr
      };
    4. Create the response data.

      See the End panel of GET /sample_products endpoint and modify the code as below to format the image data (from flickr).

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      flickr.photos.search(options, function(error, result) {
      result.photos.photo.map(function(value) {
      photoList.push(
      {
      _id: value.id,
      name: value.title,
      image_url: 'https://farm' + value.farm + '.staticflickr.com/' + value.server + '/' + value.id + '_' + value.secret + '.jpg',
      type: 'flickr',
      category: '',
      }
      );
      });

      var loughMaxCount = photoList.length < options.per_page ?
      ((options.page + 1) * photoList.per_page + photoList.length) : 100;

      next({
      images: photoList,
      count: loughMaxCount,
      });
      });
  3. Add a WebAPI named image/google and activate GET.

  4. Edit the API Logic of GET image/google endpoint.

    1. Select the GET image/google endpoint.

    2. Add the Google Search Web API Logic from Search menu at the right pane.

    3. Edit the code for options such as query string and paging number.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      var headers = {
      'Content-Type': 'application/json'
      };

      var options = {
      url: url,
      method: 'GET',
      headers: headers,
      json: true,
      qs: {
      searchType:'image',
      key: '[API Key]',
      cx: '[Custom Search Engine ID]',
      q: req.query.keyword || 'image',
      start: req.query.offset + 1,
      num: req.query.limit || 100,
      },
      };
    4. Create the response data.

      See the End panel of GET /sample_products endpoint and modify the code as below to return a response similar to the endpoint.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      Request(options, function(error, response, body) {
      if (!error && response.statusCode == 200) {
      next({
      images: body.items.map(function(value) {
      return {
      _id: value.link,
      name: value.title,
      image_url: value.link,
      type: 'google',
      category: '',
      };
      }),
      count: body.searchInformation.totalResults
      });
      }
      });
  5. Download the application.

Customize the application

Frontend

  1. Edit the actions/ProductActionCreators.js

    Add the var url to switch URL by types and modify the dispatch parameter.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    const ProductActionCreators = {
    getProducts({ offset = 0, limit = 9, keyword, types }) {
    var url = types === 'flickr' ? '/image/flickr' : '/image/google';

    const getProducts = api.get(url, {
    params: {
    offset,
    limit,
    keyword,
    },
    });

    axios.all([getProducts])
    .then(axios.spread((productList) => {
    AppDispatcher.dispatch({
    type: ActionTypes.GET_PRODUCTS,
    data: {
    products: productList.data.images,
    count: productList.data.count,
    },
    });
    })).catch(() => {
    // @todo handle error
    });
    },
  2. Edit the components/FormSearchBox/FormSearchBox.js

    The form provides two search options, Flickr and Google.
    We modify the radioButtonOptions as below.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    const radioButtonOptions = (
    <RadioButtonGroup
    name="types"
    valueSelected={type}
    style={styles.radioButtonOptions}
    onChange={(event, value) => this.handleTypeChange(value)}
    >
    <RadioButton
    value="flickr"
    label="Flickr"
    style={styles.radioButton}
    />
    <RadioButton
    value="google"
    label="Google"
    style={styles.radioButton}
    />
    </RadioButtonGroup>
    );
  3. Edit the components/containers/ProductListContainers.js

    Change types property of ProductActionCreators.getProducts parameter.

    1
    2
    // types: filter.type === 'All' ? ['X', 'Y'] : [filter.type],
    types: filter.type,
  4. Edit the stores/FilterStore.js

    Change default value for type.

    1
    2
    3
    4
    5
    getInitialState() {
    return {
    data: Immutable.fromJS({
    keyword: '',
    type: 'flickr',

Backend

Nothing to be edited.

Deploy the application

Finally, you are ready to deploy your application.

Backend

1
2
cd backend
cf push [APP_NAME]

Frontend

1
2
3
4
5
6
cd frontend
npm install
set API_URL=[Backend URL] # for Windows
export API_URL=[Backend URL] # for Mac/Linux
npm run build
cf push [APP_NAME] -p public

Download

Version

  • Form Search Template: v1.0.0