You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于NativeScript-BarcodeScanner调用Google Books API展示图书信息

Hey there! Let's fix up your code to make it properly query the Google Books API after scanning an ISBN, then navigate to a new page to display the book details. Here's what's off with your current code and how to fix it:

Current Issues in Your Code

  • Incorrect API Request URL: You're passing the entire result object to the API instead of the ISBN value (result.text). The URL should target the specific ISBN string from the scan.
  • Broken Response Parsing: response.content.toJSON() isn't the right way to parse API responses in NativeScript—you need to convert the response content to a string first, then parse it as JSON.
  • Missing Navigation Logic: You're just showing an alert with incorrect data instead of navigating to a dedicated page to display book details.
  • Mismatched Scan Method Parameters: Your scan() method is defined without parameters, but you're calling it with arguments in doScanWithTorch and doScanLandscape.

Fixed hardcopy-view-model.js Code

var observable_1 = require("data/observable");
var dialogs_1 = require("ui/dialogs");
var nativescript_barcodescanner = require("nativescript-barcodescanner");
const httpModule = require("http");
var frameModule = require("ui/frame"); // Add frame module for page navigation

var BarCodeModel = (function (_super) {
    __extends(BarCodeModel, _super);

    function BarCodeModel() {
        _super.call(this);
        this.barcodeScanner = new nativescript_barcodescanner.BarcodeScanner();
    }

    BarCodeModel.prototype.doCheckHasCameraPermission = function () {
        this.barcodeScanner.hasCameraPermission().then(function (permitted) {
            dialogs_1.alert({
                title: "Has Camera permission?",
                message: permitted ? "YES" : "NO",
                okButtonText: "OK"
            });
        }, function (err) {
            dialogs_1.alert(err);
        });
    };

    // Fix scan method to accept and use parameters
    BarCodeModel.prototype.scan = function (showFlipCameraButton, preferFrontCamera, showTorchButton, orientation) {
        this.barcodeScanner.scan({
            cancelLabel: "EXIT. Also, try the volume buttons!",
            cancelLabelBackgroundColor: "#333333",
            message: "Tap the bulb button or Use the volume button for turning on light",
            showFlipCameraButton: showFlipCameraButton || false,
            preferFrontCamera: preferFrontCamera || false,
            showTorchButton: showTorchButton || true,
            beepOnScan: true,
            torchOn: false,
            closeCallback: function () {
                console.log("Scanner closed");
            },
            resultDisplayDuration: 500,
            orientation: orientation || "landscape",
            openSettingsIfPermissionWasPreviouslyDenied: true
        }).then(
            function(result) {
                console.log("---- scanned ISBN: " + result.text);
                
                // Correct API URL with the scanned ISBN value
                const apiUrl = `https://www.googleapis.com/books/v1/volumes?q=isbn:${result.text}`;
                
                httpModule.request({
                    url: apiUrl,
                    method: "GET"
                }).then((response) => {
                    // Parse response correctly: convert to string first, then JSON
                    const responseString = response.content.toString();
                    const bookData = JSON.parse(responseString);
                    
                    console.log("Book API Response: ", bookData);
                    
                    // Handle case where no book matches the ISBN
                    if (bookData.totalItems === 0) {
                        dialogs_1.alert({
                            title: "No Book Found",
                            message: "No book matching this ISBN was found in Google Books.",
                            okButtonText: "OK"
                        });
                        return;
                    }
                    
                    // Extract relevant book details from the API response
                    const volumeInfo = bookData.items[0].volumeInfo;
                    const bookDetails = {
                        title: volumeInfo.title || "Unknown Title",
                        authors: volumeInfo.authors ? volumeInfo.authors.join(", ") : "Unknown Authors",
                        publishedYear: volumeInfo.publishedDate ? volumeInfo.publishedDate.substring(0,4) : "Unknown Year",
                        description: volumeInfo.description || "No description available."
                    };
                    
                    // Navigate to the book detail page (replace with your actual page path)
                    frameModule.topmost().navigate({
                        moduleName: "book-detail/book-detail",
                        context: bookDetails, // Pass book data to the new page
                        animated: true
                    });
                    
                }, (httpError) => {
                    console.error("HTTP Request Error: ", httpError);
                    dialogs_1.alert({
                        title: "Error",
                        message: "Failed to fetch book information. Please try again.",
                        okButtonText: "OK"
                    });
                });
            },
            function(error) {
                console.log("No scan: " + error);
                dialogs_1.alert({
                    title: "Scan Cancelled",
                    message: "Barcode scanning was cancelled or failed.",
                    okButtonText: "OK"
                });
            });
    };

    BarCodeModel.prototype.doScanWithTorch = function () {
        this.scan(false, false, true, "landscape");
    };

    BarCodeModel.prototype.doScanLandscape = function () {
        this.scan(false, false, true, "landscape");
    };

    return BarCodeModel;
}(observable_1.Observable));

exports.BarCodeModel = BarCodeModel;

Setting Up the Book Detail Page

  1. Create a new page UI (book-detail/book-detail.xml) to display book info:
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded">
    <StackLayout padding="20">
        <Label text="{{ title }}" class="h2 text-center" />
        <Label text="{{ authors }}" class="h4 text-center text-gray" marginTop="10" />
        <Label text="Published: {{ publishedYear }}" class="text-center" marginTop="5" />
        <Label text="{{ description }}" class="mt-20" textWrap="true" />
    </StackLayout>
</Page>
  1. Create the view-model for the detail page (book-detail/book-detail-view-model.js):
var observable_1 = require("data/observable");

var BookDetailModel = (function (_super) {
    __extends(BookDetailModel, _super);

    function BookDetailModel(bookData) {
        _super.call(this);
        this.set("title", bookData.title);
        this.set("authors", bookData.authors);
        this.set("publishedYear", bookData.publishedYear);
        this.set("description", bookData.description);
    }

    return BookDetailModel;
}(observable_1.Observable));

exports.BookDetailModel = BookDetailModel;
  1. Update the detail page code-behind (book-detail/book-detail.js) to load the passed data:
var BookDetailModel = require("./book-detail-view-model").BookDetailModel;

function pageLoaded(args) {
    var page = args.object;
    var bookData = page.navigationContext;
    page.bindingContext = new BookDetailModel(bookData);
}
exports.pageLoaded = pageLoaded;

内容的提问来源于stack exchange,提问作者LSA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:49:22