3

I am currently trying to create an autocomplete search with the element-api. I need results from two different elementTypes:

  • Product::class
  • Entry::class

How do I get results out of both elementTypes with only one endpoint?

Thats my working Product::class element-api.php config file:

return [
    'endpoints' => [
        'search.json' => function() {
        // settings
        $phrase = Craft::$app->request->getParam('query');

        $criteria = [
            'search' => 'title:'.$phrase,
        ];

            return [
                'elementType' => Product::class,
                'criteria' => $criteria,
                'paginate' => false,
                'transformer' => function(Product $product) {
                return [
                    'title' => $product->title,
                    'url' => $product->url,
                ];
            },
          ];

        },
    ]
];
1

The results query could not be the same, you have to separate them.

use craft\commerce\elements\Product;
use craft\elements\Entry;

return [
    'endpoints' => [
        'search/product.json' => function () {
            // settings
            $phrase   = Craft::$app->request->getParam('query');
            $criteria = [
                'search' => 'title:' . $phrase,
            ];

            return [
                'elementType' => Product::class,
                'criteria'    => $criteria,
                'paginate'    => false,
                'transformer' => function (Product $product) {
                    return [
                        'title' => $product->title,
                        'url'   => $product->url,
                    ];
                },
            ];
        },
        'search/news.json' => function () {
            // settings
            $phrase   = Craft::$app->request->getParam('query');
            $criteria = [
                'search' => 'title:' . $phrase,
            ];

            return [
                'elementType' => Entry::class,
                'criteria'    => $criteria,
                'paginate'    => false,
                'transformer' => function (Entry $entry) {
                    return [
                        'title' => $entry->title,
                        'url'   => $entry->url,
                    ];
                },
            ];
        },
    ]
];

UPDATED: 18/12/2020

Anyway, I've found a new way that allows you o use the multiple entries in an endpoint.

<?php

use craft\commerce\elements\Product;
use craft\elements\Entry;

return [
    'endpoints' => [
        'search.json' => function () {
            // settings
            $phrase         = \Craft::$app->request->getParam('query');
            $articles       = Entry::find()->search($phrase)->limit(10)->all();
            $articleObjects = [];

            if ($articles) {
                $articleTemplateName = ''; // your article template path
                foreach ($articles as $article) {
                    $articleObjects[] = \Craft::$app->getView()->renderTemplate($articleTemplateName, ['post' => $article]);
                }
            }

            return [
                'elementType' => Product::class,
                'criteria'    => [
                    'search' => 'title:' . $phrase,
                ],
                'paginate'    => false,
                'transformer' => function (Product $product) {
                    return [
                        'title' => $product->title,
                        'url'   => $product->url,
                    ];
                },
                'meta'        => [
                    'news' => $articleObjects
                ]
            ];
        },
    ]
];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.