jesse_orange_newable's avatar

Pulling a dataset and only importing certain items

I am using an API to pull in a large data set, I am then rendering a table with HTML where users can tick which items they'd like to import.

Here is my controller


<?php

namespace App\Http\Controllers\Admin;

use App\Events\DealImportedFromHubspot;
use App\Http\Controllers\Controller;
use App\Hubspot\PipelineHubspot;
use App\Models\Deal;
use App\Models\DealStage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class DealImportController extends Controller
{
    /**
     * An array to store imported Deals
     *
     * @var array
     */
    private $importedDeals = [];

    /**
     * Create a new controller instance.
     */
    public function __construct()
    {
        $this->excludedDealStages = DealStage::excludeFromDealImport()->pluck('hubspot_id');
    }

    /**
     * Display the page to start the import process.
     *
     * @return void
     */
    public function index()
    {
        return view('pages.user.deal.import');
    }

    /**
     * Check for Deals to import and then display a listing.
     *
     * @return void
     */
    public function check()
    {
        $this->getDealsFromHubspot();

        session()->put('deals', $this->importedDeals);

        return view('pages.user.deal.import', [
            'count' => count($this->importedDeals),
            'deals' => $this->importedDeals,
        ]);
    }

    /**
     * Import all selected Deals.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return void
     */
    public function import(Request $request)
    {
        $request->validate([
            'imports' => [
                'required',
                'array',
            ],
        ]);

        if ($request->has('imports')) {
            PipelineHubspot::import();

            $selections = $request->get('imports');
            $importedDeals = session()->get('deals');

            foreach ($selections as $selection) {
                foreach ($importedDeals as $deal) {
                    if ($selection == $deal['hs_object_id']) {
                        $this->syncDeal($deal);
                    }
                }
            }

            session()->forget('deals');

            return redirect()->route('admin.dashboard')->withSuccess(count($selections) . ' deals were imported');
        }
    }

    /**
     * Grab Deals from Hubspot by calling the Deals API and looping through the paginated data
     *
     * @param int    $limit: the number of deals per page
     * @param string $next:  the link to the next page of results
     */
    private function getDealsFromHubspot(?int $limit = 100, string $next = null)
    {
        $endpoint = 'https://api.hubapi.com/crm/v3/objects/deals';

        $properties = [
            'limit' => $limit,
            'properties' => implode(',', Deal::HUBSPOT_DEAL_PROPERTIES),
            'hapikey' => config('hubspot.api_key'),
            'associations' => 'engagements',
        ];

        // If there's another page, append the after parameter.
        if ($next) {
            $properties['after'] = $next;
        }

        $response = Http::get($endpoint, $properties);

        if ($response->successful()) {
            $data = $response->json();

            // If there are results, get them.
            if (isset($data['results'])) {
                foreach ($data['results'] as $hubspotDeal) {
                    if (!$this->excludedDealStages->contains($hubspotDeal['properties']['dealstage'])) {
                        $this->importedDeals[] = $hubspotDeal['properties'];
                    }
                }
            }

            // If there's paginate we need to call the function on itself
            if (isset($data['paging']['next']['link'])) {
                $this->getDealsFromHubspot(null, $data['paging']['next']['after']);
            }
        }
    }

    /**
     * Sync the Deal data with a model instance.
     * Generate the necessary links and send them back to HubSpot.
     *
     * @see App\Events\DealImportedFromHubspot
     *
     * @param array $data
     *
     * @return void
     */
    private function syncDeal(array $data)
    {
        $excludedDealStages = DealStage::excludeFromDealImport()->pluck('hubspot_id');

        if ($excludedDealStages->contains($data['dealstage'])) {
            return false;
        }

        $deal = Deal::updateOrCreate([
            'hubspot_id' => $data['hs_object_id'],
        ], [
            'name' => $data['dealname'],
            'deal_stage_id' => $data['dealstage'],
            'hubspot_owner_id' => $data['hubspot_owner_id'] ?? null,
        ]);

        event(new DealImportedFromHubspot($deal));
    }
}



The issue I'm having is that when there's roughly a thousand or so, rendering the table will hang the browser.

I was wondering whether I should just use something like Vue as then I can store the selections, any pagination etc in the virtual DOM rather then checking and then reloading the page?

0 likes
0 replies

Please or to participate in this conversation.