Flutter fetch data from img src with html parse - html

Html Codes
I have to get "<img src=" value. How can i do this?
I tried this :
responseBody = responseBody.substring(responseBody.indexOf('<img src=""'));
var lt = responseBody.substring(0, responseBody.indexOf('" />'));
and this :
for (var i = 0; i < count; i++) {
print(document.getElementsByClassName("firma-isim")[i].getElementsByTagName("img")[0].getElementsByTagName("src").first;
}
But didn't work. Is there an easy way to do this? How can I do this?
Thanks.
HTML :
<div class="populer-firmalar">
<span class="firma-sol" data-kaydir=".pop-firma,sol,1"><i class="fa fa-angle-left"></i></span>
<span class="firma-sag" data-kaydir=".pop-firma,sag,1"><i class="fa fa-angle-right"></i></span>
<div class="populer-firma-holder">
<ul class="pop-firma">
<li class="active">
<div class="firma-resim">
<img src="https://kimbufirma.com/firma/wp-content/uploads/2021/02/a3-dijital-web-tasarim-ve-yazilim-ajansi.cropped.270x200.jpg" alt="A3 DİJİTAL | WEB TASARIM VE YAZILIM AJANSI" width="270" height="200">
</div>

You can use html parser and html dom
var document = parse(body);
dom.Element link = document.querySelector('img');
String imageLink = link != null ? link.attributes['src'] : '';
Make sure to import these
import 'package:html/dom.dart' as dom;
import 'package:html/parser.dart' show parse;

I use Regular Expressions:
NetService:
import 'dart:convert';
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:path/path.dart' as p;
class NetService {
/* ---------------------------------------------------------------------------- */
static Future<T> getJson<T>(String url) {
return http.get(Uri.parse(url))
.then((response) {
if (response.statusCode == 200) {
return jsonDecode(response.body) as T;
}
print('Status Code : ${response.statusCode}...');
return null;
})
.catchError((err) => print(err));
}
/* ---------------------------------------------------------------------------- */
static Future<String> getRaw(String url) {
return http.get(Uri.parse(url))
.then((response) {
if (response.statusCode == 200) {
return response.body;
}
print('Status Code : ${response.statusCode}...');
return null;
})
.catchError((err) => print(err));
}
}
Main:
import 'dart:async';
import 'package:_samples2/networking.dart';
const kUrl = 'https://kimbufirma.com/firma/';
var regExp = RegExp(r'<a href="[\w\d\:\.\-\/]+"><img src="([\w\d\:\.\-\/]+)"');
class WebSite {
static Future<String> fetchWebPage () async {
print('Start fetching...');
return await NetService.getRaw(kUrl)
.whenComplete(() => print('Fetching done!\n'));
}
}
void main(List<String> args) async {
var data = await WebSite.fetchWebPage();
var images = regExp.allMatches(data).map((e) => e.group(1)).toList();
// print(images);
print(images.where((e) => e.contains('a3')));
print(images[1]);
}
Result:
Start fetching...
Fetching done!
(https://kimbufirma.com/firma/wp-content/uploads/2021/02/a3-dijital-web-tasarim-ve-yazilim-ajansi.cropped.270x200.jpg)
https://kimbufirma.com/firma/wp-content/uploads/2021/02/a3-dijital-web-tasarim-ve-yazilim-ajansi.cropped.270x200.jpg

Related

Uploading multiple images using angular and send them to api

im using angular as front-end and trying to upload 2 images and then send them as a string to OCR API,
here is my code
let reader:FileReader = new FileReader();
let image = new Image();
var file;
for (var i = 0; i < imgFile.target.files.length; i++){
file = imgFile.target.files[i]
reader.onload = (e: any) => {
image.src = e.target.result;
image.onload = rs => {
//console.log(reader.result);
this.fileString = image.src;
};
};
reader.readAsDataURL(file)
}
the problem is I cant send the files to the API , as I don't know how to get the image data as a string to send them together
what can I do?
Plenty of examples, but you need an upload service with the correct Backend URL to the API, this one can do any file type. Just filter out the file type you dont want in the upload function
POST /upload Upload a file
GET /files Get a list of files
GET /files/[filename] Download a file
src/app/upload.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpRequest, HttpEvent } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class UploadService {
private serverUrl = 'http://localhost:8080';
constructor(private httpClient: HttpClient) { }
upload(file: File): Observable<HttpEvent<any>> {
const formData: FormData = new FormData();
formData.append('file', file);
const request = new HttpRequest('POST', `${this.serverUrl}/upload`, formData, {
reportProgress: true,
responseType: 'json'
});
return this.httpClient.request(request);
}
getFiles(): Observable<any> {
return this.httpClient.get(`${this.serverUrl}/files`);
}
}
Create and MultiImageUploadComponent.ts
import { Component, OnInit } from '#angular/core';
import { UploadService } from 'src/app/upload.service';
import { HttpEventType, HttpResponse } from '#angular/common/http';
import { Observable } from 'rxjs';
export class UploadComponent implements OnInit {
selectedFiles: FileList;
progressInfos = [];
message = '';
fileInfos: Observable<any>;
constructor(private uploadService: UploadService) { }
}
ngOnInit(): void {
this.fileInfos = this.uploadService.getFiles();
}
selectFiles(e): void {
this.progressInfos = [];
this.selectedFiles = e.target.files;
}
uploadFiles(): void {
this.message = '';
for (let i = 0; i < this.selectedFiles.length; i++) {
this.upload(i, this.selectedFiles[i]);
}
}
upload(idx, file): void {
this.progressInfos[idx] = { value: 0, fileName: file.name };
this.uploadService.upload(file).subscribe(
event => {
if (event.type === HttpEventType.UploadProgress) {
this.progressInfos[idx].value = Math.round(100 * event.loaded / event.total);
} else if (event instanceof HttpResponse) {
this.fileInfos = this.uploadService.getFiles();
}
},
err => {
this.progressInfos[idx].value = 0;
this.message = 'Could not upload the file:' + file.name;
});
}
your HTML template
<div *ngFor="let progressInfo of progressInfos" class="mb-2">
<span>{{ progressInfo.fileName }}</span>
<div class="progress">
<div
class="progress-bar progress-bar-info progress-bar-striped"
role="progressbar"
attr.aria-valuenow="{{ progressInfo.value }}"
aria-valuemin="0"
aria-valuemax="100"
[ngStyle]="{ width: progressInfo.value + '%' }"
>
{{ progressInfo.value }}%
</div>
</div>
</div>
<label class="btn btn-default">
<input type="file" multiple (change)="selectFiles($event)" />
</label>
<button
class="btn btn-success"
[disabled]="!selectedFiles"
(click)="uploadFiles()">
Upload
</button>
<div class="alert alert-light" role="alert">{{ message }}</div>
<div class="card">
<div class="card-header">List of Files</div>
<ul
class="list-group list-group-flush"
*ngFor="let file of fileInfos | async"
>
<li class="list-group-item">
{{ file.name }}
</li>
</ul>
</div>
You can call it like so from your app, where <app-upload> is your directive/component above
<h1>{{ title }}</h1>
<div class="container">
<app-upload></app-upload>
</div>
Make sure the OCR API is wired up to the services to invoke & POST

Flutter Provider for Cart page

I need to make a cart page for an e-commerce app. where I am getting JSON data from API.
I can fetch the data and show data. but when it's matter to cart I cannot add this data to my provider page.
This is MY Provider Page For Album
import 'package:flutter/material.dart';
import 'package:provider_test/albumModel.dart';
import '../Service/service.dart';
class MyStore extends ChangeNotifier {
List<Album> _albums = [];
List<Album> _busket = [];
Album _activeAlbum = null;
List<Album> get albums => _albums;
List<Album> get buskets => _busket;
Album get activeAlbum => _activeAlbum;
}
And this is my Album Model Page:
import 'dart:convert';
import 'package:flutter/cupertino.dart';
List<Album> allalbumsFromJson(String str) {
final jsonData = json.decode(str);
return new List<Album>.from(jsonData.map((x) => Album.fromJson(x)));
} //ef
class AlbumList with ChangeNotifier {
final List<Album> albums;
AlbumList({
this.albums,
});
factory AlbumList.fromJson(List<dynamic> parsedJson) {
List<Album> albums = List<Album>();
albums = parsedJson.map((i) => Album.fromJson(i)).toList();
return AlbumList(albums: albums);
}
notifyListeners();
} //ef
class Album with ChangeNotifier {
int userId;
int id;
String title;
Album({this.userId, this.id, this.title});
Album.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
id = json['id'];
title = json['title'];
}
notifyListeners();
} //ef
Album albumFromJson(String str) {
final jsonData = json.decode(str);
return Album.fromJson(jsonData);
} //ef
Now I can fetch Data Using this Function:
import 'package:flutter/cupertino.dart';
import 'package:provider_test/albumModel.dart';
import 'package:http/http.dart' as HTTP;
final url = ('https://jsonplaceholder.typicode.com/albums');
Future<List<Album>> getAllAlbum() async {
final response = await http.get(url);
// print(response.body);
return allalbumsFromJson(response.body);
}
Future<Album> getAlbum() async {
final response = await http.get('$url/1');
return albumFromJson(response.body);
}
How Can I insert getAllAlbums() Data or you can say List Data into the _albums=[] which is situated in Mystore Page?
Hi for the cart I think you the best way you must use a map instead of a list like below:
Map<int, FavoriteModel> _favoites = {};
Map<int, FavoriteModel> get favoitesItem {
return _favoites;
}
And for adding data from you can use of this method:
void addOrRemoveSingleItem({
int foodId,
String title,
double price,
String imageUrl,
int userId
}) async {
if (_favoites.containsKey(foodId)) {
try {
final res = await http.post(
addFavoriteUrl,
body: {
"user_id": userId.toString(),
"food_id": foodId.toString(),
"Is_delete": "1",
},
);
} catch (e) {
print(e);
throw (e);
}
} else {
try {
_favoites.putIfAbsent(
foodId,
() => FavoriteModel(
id: foodId,
name: title,
regularPrice: price,
featureImage: imageUrl,
),
);
http.post(
addFavoriteUrl,
body: {
"user_id": userId.toString(),
"food_id": foodId.toString(),
},
);
} catch (e) {
print(e);
throw (e);
}
}
notifyListeners();
}

Java Spring: How convert HTML character codes in hex format from textarea to plain text?

I have web application writed in React JS and Java Spring boot. In my Board Component I have form with textarea and button. While debugging when I click on button I am redirect to PostMapping in UserController spring project. My method has one parameter. It's #RequestBody String query.
I get text from textarea in HTML character codes in hex code. I need to plain text from this String.
I get something what look like this:
CREATE+TABLE+users+%28%0A%09id+INT%2C%0A%09fullName+VARCHAR%28220%29+NOT+NULL%2C%0A%09city+VARCHAR%28120%29+NOT+NULL%2C%0A%09country+VARCHAR%2860%29+NOT+NULL%2C%0A%09PRIMARY+KEY%28id%29%0A%29%3 ...
where + does mean space
I was trying resolve this problem.
Nothing works.
First way:
byte[] s = DatatypeConverter.parseHexBinary(query);
System.out.println(new String(s, "UTF-8"));
Second way:
Apache Commons Codec - Hex
byte[] bytes = Hex.decodeHex(query.toCharArray());
System.out.println(new String(bytes, "UTF-8"));
Here is my code
Spring project:
UserController class
#Controller
#RequestMapping("fiddle")
public class MainController {
#PostMapping
public ResponseEntity<?> processingQueries(#RequestBody String query) {
System.out.println(query);
return new ResponseEntity<String>("Query prcessed successfully.", HttpStatus.OK);
}
}
React JS project:
Board component
import React from 'react';
import TableButton from './TableButton';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { processQueries } from '../actions/queryActions';
class Board extends React.Component {
constructor() {
super();
this.state = {
query: 'Write here your SQL query...'
}
this.onChange = this.onChange.bind(this);
this.resetField = this.resetField.bind(this);
this.onSubmitRun = this.onSubmitRun.bind(this);
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
resetField(e) {
this.setState({ query: '' });
}
onSubmitRun(e) {
e.preventDefault();
console.log(this.state.query);
this.props.processQueries(this.state.query, this.props.history);
}
render() {
return (
<div className="box flex-stretch">
<div className="blue smallClass">
<TableButton />
</div>
<div className="mediumClass">
<form onSubmit={this.onSubmitRun}>
<textarea
name="query"
className="txtArea"
value={this.state.query}
onChange={this.onChange}
onClick={this.resetField}
rows="27"
>
Write here your SQL queries...
</textarea>
<input type="submit" value="Run" className="runButton"/>
</form>
</div>
<div className="red largeClass">
One of three columns
</div>
</div>
);
}
}
Board.propTypes = {
query: PropTypes.string
}
const mapStateToProps = state => ({
query: state.query
})
export default connect(mapStateToProps, { processQueries })(Board);
queryReducer
import { PROCESS_QUERY } from '../actions/types';
const initialState = {
query: ''
}
export default function(state = initialState, action) {
switch(action.type) {
case PROCESS_QUERY:
return {
...state,
query: action.payload
}
default:
return state;
}
}
queryActions
import axios from 'axios';
import { GET_ERRORS, PROCESS_QUERY } from './types';
export const processQueries = (query, history) => async dispatch =>
{
try {
console.log(query);
await axios.post("/fiddle", query);
history.push("/fiddle");
dispatch({
type: PROCESS_QUERY,
payload: ''
})
} catch(error) {
dispatch({
type: GET_ERRORS,
payload: error.response.data
})
}
}
I need to convert this string from textarea to plain text. Data inserted to textarea are plan SQL queries.
All you need to decode string with UrlDecoder.
String result = java.net.URLDecoder.decode(query, StandardCharsets.UTF_8.displayName());

What is dispose of null in Angular 4

I am getting "what is dispose of null" when load the page.
I am to get list of data but unable to show those record in view.
Here i added code snippet to understand my requirement
Angular JS Service File
import { Injectable } from '#angular/core';
import { Http, Headers, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class PostsService {
data: any = null;
totalDocs: number;
url: any = 'http://localhost:3000/services/';
constructor(private _http: Http) { }
public getPosts() {
return this._http.get(this.url + 'posts')
.map((res: Response) => res.json());
}
}
//End Angular JS Web service*
Node JS code to get data from MongoDB
import { default as Category} from "../models/Category";
import { default as Post} from "../models/Post";
import { Request, Response, NextFunction } from "express";
export let getPostsAPI = (req: Request, res: Response, next: NextFunction) => {
const post: any = req.body;
const cond: any = {};
if (!this.empty(post.kword)) {
*//$text is full text index*
cond.$text = {$search : post.kword};
}
if (!this.empty(post.location)) {
cond.city = {$regex: new RegExp("^" + post.location, "i") };
}
*Counting total number of records and
Here Post is reference of collection, its working fine and generating data as i given bottom of this post.*
Post.count(cond).then(totalDocs => {
Post.find(cond).sort({created_at: -1}).then(result => {
const results = {data: result, totalDocs: totalDocs};
console.log(results);
res.end("" + JSON.stringify(results));
});
});
};
End node JS Code
Angular JS home.component.ts where i am calling web serive to render data in angular view
export class HomeComponent implements OnInit {
results: any = {};
model: any = {};
constructor(private posts: PostsService) {
posts.getPosts().subscribe(res => {
console.log(res.totalDocs); // Showing number of records in console.
this.results = res.data; // this is throwing error.
*//Error is: TypeError: Cannot read property 'dispose' of null*
});
this.model.kword = '';
this.model.location = '';
}
ngOnInit() {
}
}
Template Code
<div class="container">
<app-filter [result]=value (clicked)="searchJob($event)"></app-filter>
<!-- /.row -->
<div class="row" >
<div class="col-sm-10 my-10" *ngFor="let post of results | async">
<div class="card">
<div class="card-body">
<h3 class="mt-1"><a [routerLink]="['/job', post.company, post.title, post._id]">{{ post.title }}</a></h3>
<p class="mt-1" *ngIf="post.company"><span class="badge badge-primary">{{post.company}}</span></p>
<p class="mt-1" *ngIf="post.salary_min">Salary up to: ₹{{post.salary_min}} - ₹{{post.salary_max}}</p>
<p class="mt-1" *ngIf="post.city || post.state">Location: {{post.city}}, <span *ngIf="post.state">{{post.state}}</span></p>
<p class="mt-1" *ngIf="post.description">{{post.description | slice:0:150}}[...]</p>
</div>
</div>
</div>
</div>
<!-- /.row -->
</div>
End Template
JSON DATA WHICH COMING FROM API
{
"data":
[
{
"title":"test title",
"description":"test description"
}
],
"totalRecords":2
}
i attached a screenshot of error.
The async pipe subscribes to an observable for you, so it needs to be fed an observable, you're feeding it the resulting value of an observable, which is why you're seeing this error.
Do it like this instead:
results: Observable<any>;
model: any = {};
constructor(private posts: PostsService) {
this.results = posts.getPosts().map(res => res.data);
this.model.kword = '';
this.model.location = '';
}
Now you're setting the "results" value to the actual observable, and letting async handle the subscription part.

Redux loses state when navigating to another page using react-router 'history.push'

(as you can see my reputation is not very high :) and I understand that if you don't like my question it is going to be my last one, therefore I am going to write it as good as I can :)
The problem I am facing is a similar to:
Redux loses state when navigating to another page
However, the answer to the above question was to use 'history.push', which is what I am doing, and I am still having a problem.
I am using:
"react": "^16.0.0"
"react-redux": "^5.0.6"
"react-router": "^4.2.0"
"react-router-dom": "^4.2.2"
"redux": "^3.7.2"
"redux-promise":"^0.5.3"
"axios": "^0.17.1"
I am doing the following:
In a react component, "SearchText", getting a text string and calling an action creator
In the action creator, using the text string to send an HTTP request to goodreads.com
In my reducer, using the action payload to set the redux state
Using another component, "BookResults" (in another route), to display this state
The component "SearchText" has a link to the "BookResults" page.
So, once "SearchText" fires the action creator, if (when I see on the console that a result is received and the state is set with a list of books) I click on the link that routes to "BookResults", I see the list of books.
If, however, "SearchText" uses (when firing the action creator) a callback that performs history.push of the new page, and this callback is called by 'axios(xxx).then', the state is not set properly, although I see in the console that the HTTP request was successful.
I am sure you can see what I am doing wrong (and I hope it is not very stupid)... Please tell me.
Here is the code:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise';
import SearchText from './components/search_text';
import BookResults from './components/book_results';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<div>
<BrowserRouter>
<Switch>
<Route path="/book_results" component={BookResults} />
<Route path="/" component={SearchText} />
</Switch>
</BrowserRouter>
</div>
</BrowserRouter>
</Provider>
, document.querySelector('#root'));
SearchText component
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Link } from 'react-router-dom';
import { searchForBooks } from '../actions';
class SearchText extends Component {
constructor(props) {
super(props);
this.state = {
searchText: ''
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleSearchTextChange = this.handleSearchTextChange.bind(this);
}
handleSearchTextChange(e) {
this.setState({ searchText: e.target.value });
}
handleFormSubmit(e) {
e.preventDefault();
const formPayload = {
searchText: this.state.searchText
};
console.log("In SearchBooks/handleFormSubmit. Submitting. state: ", this.state);
this.props.searchForBooks(formPayload, () => {
this.props.history.push(`/book_results`);
});
}
render() {
return (
<form className="container" onSubmit={this.handleFormSubmit}>
<h3>Search Form</h3>
<div className="form-group">
<label className="form-label">{'Search Text:'}</label>
<input
className='form-input'
type='text'
name='searchText'
value={this.state.searchText}
onChange={this.handleSearchTextChange}
onBlur={this.handleSearchTextBlur}
placeholder='' />
</div>
<br />
<input
type="submit"
className="btn btn-primary float-right"
value="Submit"/>
<br /><br />
<Link to={`/book_results`}>⇐ Book Results</Link>
</form>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ searchForBooks: searchForBooks }, dispatch);
}
export default connect(null, mapDispatchToProps)(SearchText);
BookResults component
import React from 'react';
import { connect } from 'react-redux';
import _ from 'lodash';
import Book from './book';
class BookResults extends React.Component {
render() {
let books;
const booksArray = _.values(this.props.bookResults);
console.log("***In BookResults. booksArray: ", booksArray);
if (booksArray.length === 0) {
books = "No books to display";
} else {
books = booksArray.map( (book) => {
return (
<Book book={book} key={book.id} />
);
});
}
return (
<div>
<h2>Search Results</h2>
<br />
<ul>
{books}
</ul>
</div>
);
}
}
function mapStateToProps(state) {
return {
bookResults: state.bookResults,
cats: state.cats
};
}
export default connect(mapStateToProps)(BookResults);
Book component
import React from 'react';
const Book = (props) => (
<li>
{props.book.title}
</li>
);
export default Book;
actions/index.js
As you can see below, the following line is commented out:
// .then(() => callback());
If I include it, I have the problem.
import axios from 'axios';
export const SEARCH_FOR_BOOKS = 'search_for_books';
const GOODREADS = "https://www.goodreads.com/search/index.xml";
const KEY = "xxx";
export function searchForBooks(values, callback) {
let result;
console.log("In actions/searchForBooks. values: ", values);
if (!values.searchText || values.searchText === "") {
console.error("*** ERROR *** In actions/searchForBooks." +
"values.searchText: ", values.searchText);
} else {
const searchUrl = `${GOODREADS}?key=${KEY}&q=${values.searchText}`;
console.log("In actions/searchForBooks. url: " + searchUrl);
result = axios.get(searchUrl);
// .then(() => callback());
}
return {
type: SEARCH_FOR_BOOKS,
payload: result
};
}
reducers/index.js
import { combineReducers } from 'redux';
import bookResultsReducer from './reducer_book_results';
const rootReducer = combineReducers({
bookResults: bookResultsReducer
});
export default rootReducer;
The reducer
import { parseString } from 'xml2js';
import _ from 'lodash';
import { SEARCH_FOR_BOOKS } from '../actions/index';
const bookResults = {};
export default function bookResultsReducer(state = bookResults, action) {
switch (action.type) {
case SEARCH_FOR_BOOKS:
console.log("In bookResultsReducer. payload: ", action.payload);
if (action.error) { // error from goodreads search books
console.error("*** APP ERROR *** In bookResultsReducer. action.error: ", action.error);
} else if (!action.payload || !action.payload.data) {
console.error("*** APP ERROR *** In bookResultsReducer." +
" action.payload or action.payload.data is undefined", action.payload);
} else {
parseString(action.payload.data, function(err, result) {
if (err) {
console.error("*** APP ERROR *** In bookResultsReducer. Error from parseString: ", err);
} else {
state = Object.assign({}, getBooks(result));
}
});
}
console.log("In bookResultsReducer. new state: ", state);
return state;
break;
default:
return state;
}
}
function getBooks(data) {
const bookResults = data.GoodreadsResponse.search[0].results[0].work;
if (!bookResults || bookResults.length === 0) {
return {};
} else {
const results = bookResults.map( (book, index) => {
const bookInfo = book.best_book[0];
return (
{ id: index + 1,
title: bookInfo.title[0] }
);
});
return _.mapKeys(results, 'id');
}
}
Someone sent me the solution by mail.
The error was in the actions/index.js file.
Instead of:
import axios from 'axios';
export const SEARCH_FOR_BOOKS = 'search_for_books';
const GOODREADS = "https://www.goodreads.com/search/index.xml";
const KEY = "xxx";
export function searchForBooks(values, callback) {
let result;
console.log("In actions/searchForBooks. values: ", values);
if (!values.searchText || values.searchText === "") {
console.error("*** ERROR *** In actions/searchForBooks." +
"values.searchText: ", values.searchText);
} else {
const searchUrl = `${GOODREADS}?key=${KEY}&q=${values.searchText}`;
console.log("In actions/searchForBooks. url: " + searchUrl);
result = axios.get(searchUrl)
.then(() => callback());
}
return {
type: SEARCH_FOR_BOOKS,
payload: result
};
}
I should have written:
import axios from 'axios';
export const SEARCH_FOR_BOOKS = 'search_for_books';
const GOODREADS = "https://www.goodreads.com/search/index.xml";
const KEY = "xxx";
export function searchForBooks(values, callback) {
let result;
console.log("In actions/searchForBooks. values: ", values);
if (!values.searchText || values.searchText === "") {
console.error("*** ERROR *** In actions/searchForBooks." +
"values.searchText: ", values.searchText);
} else {
const searchUrl = `${GOODREADS}?key=${KEY}&q=${values.searchText}`;
console.log("In actions/searchForBooks. url: " + searchUrl);
result = axios.get(searchUrl)
.then((res) => {
callback();
return res;
});
}
return {
type: SEARCH_FOR_BOOKS,
payload: result
};
}
Explanation:
The issue is that the returned value from axios.get is passed to the .then clause, and whatever is returned from the .then clause is set to be the value of result.
My error was that I didn't return anything from the .then clause, and therefore the value of result was undefined, and not the returned promise.